- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设您有一个无符号整数列表。假设某些元素等于 0,并且您想将它们推回。目前我使用此代码(列表是指向大小为 n 的无符号整数列表的指针
for (i = 0; i < n; ++i)
{
if (list[i])
continue;
int j;
for (j = i + 1; j < n && !list[j]; ++j);
int z;
for (z = j + 1; z < n && list[z]; ++z);
if (j == n)
break;
memmove(&(list[i]), &(list[j]), sizeof(unsigned int) * (z - j)));
int s = z - j + i;
for(j = s; j < z; ++j)
list[j] = 0;
i = s - 1;
}
void RemoveDeadParticles(int * list, int * n)
{
int i, j = *n - 1;
for (; j >= 0 && list[j] == 0; --j);
for (i = 0; i <= j; ++i)
{
if (list[i])
continue;
memcpy(&(list[i]), &(list[j]), sizeof(int));
list[j] = 0;
for (; j >= 0 && list[j] == 0; --j);
if (i == j)
break;
}
*n = i;
}
最佳答案
下面的代码实现了我在评论中概述的线性算法:
There's a straight linear O(N) algorithm if you're careful; your's is O(N2). Given that order is irrelevant, every time you encounter a zero going forwards through the array, you swap it with the last element that might not be a zero. That's one pass through the array. Care is required on the boundary conditions.
list3[]
的酸性测试在测试代码中引起了悲伤,直到我得到了正确的边界条件。请注意,大小为 0 或 1 的列表的顺序已经正确。
#include <stdio.h>
#define DIM(x) (sizeof(x)/sizeof(*(x)))
extern void shunt_zeroes(int *list, size_t n);
void shunt_zeroes(int *list, size_t n)
{
if (n > 1)
{
size_t tail = n;
for (size_t i = 0; i < tail - 1; i++)
{
if (list[i] == 0)
{
while (--tail > i + 1 && list[tail] == 0)
;
if (tail > i)
{
int t = list[i];
list[i] = list[tail];
list[tail] = t;
}
}
}
}
}
static void dump_list(const char *tag, int *list, size_t n)
{
printf("%-8s", tag);
for (size_t i = 0; i < n; i++)
{
printf("%d ", list[i]);
}
putchar('\n');
fflush(0);
}
static void test_list(int *list, size_t n)
{
dump_list("Before:", list, n);
shunt_zeroes(list, n);
dump_list("After:", list, n);
}
int main(void)
{
int list1[] = { 1, 0, 2, 0, 3, 0, 4, 0, 5 };
int list2[] = { 1, 2, 2, 0, 3, 0, 4, 0, 0 };
int list3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int list4[] = { 0, 1 };
int list5[] = { 0, 0 };
int list6[] = { 0 };
test_list(list1, DIM(list1));
test_list(list2, DIM(list2));
test_list(list3, DIM(list3));
test_list(list4, DIM(list4));
test_list(list5, DIM(list5));
test_list(list6, DIM(list6));
}
$ shuntzeroes
Before: 1 0 2 0 3 0 4 0 5
After: 1 5 2 4 3 0 0 0 0
Before: 1 2 2 0 3 0 4 0 0
After: 1 2 2 4 3 0 0 0 0
Before: 0 0 0 0 0 0 0 0 0
After: 0 0 0 0 0 0 0 0 0
Before: 0 1
After: 1 0
Before: 0 0
After: 0 0
Before: 0
After: 0
$
i
索引向前扫描一次,
tail
index 向后扫描一次,直到两者在中间相遇。相比之下,在原始代码中,内部循环从当前索引开始,每次都向前工作到结束,这导致了二次行为。
"timer.h"
描述的代码是我的平台中立计时接口(interface);它的代码可以根据要求提供(见我的
profile)。该测试是在配备 2.3 GHz Intel Core i7、Mac OS X 10.7.5、GCC 4.7.1 的 MacBook Pro 上进行的。
int
更改为至
size_t
使外部函数接口(interface)和我的一样,并且为了内部的一致性。
$ make on2
gcc -O3 -g -I/Users/jleffler/inc -std=c99 -Wall -Wextra -L/Users/jleffler/lib/64 on2.c -ljl -o on2
$
shunt_zeroes: 100 0.000001
shunt_zeroes: 1000 0.000005
shunt_zeroes: 10000 0.000020
shunt_zeroes: 100000 0.000181
shunt_zeroes: 1000000 0.001468
pushbackzeros: 100 0.000001
pushbackzeros: 1000 0.000086
pushbackzeros: 10000 0.007003
pushbackzeros: 100000 0.624870
pushbackzeros: 1000000 46.928721
shunt_zeroes: 100 0.000000
shunt_zeroes: 1000 0.000002
shunt_zeroes: 10000 0.000011
shunt_zeroes: 100000 0.000113
shunt_zeroes: 1000000 0.000923
pushbackzeros: 100 0.000001
pushbackzeros: 1000 0.000097
pushbackzeros: 10000 0.007077
pushbackzeros: 100000 0.628327
pushbackzeros: 1000000 41.512151
on2
重命名至
timezeromoves
.
$ ./timezeromoves -c -m 100000 -n 1
shunt_zeroes: (Jonathan)
shunt_zeroes: 100 0.000001
shunt_zeroes: 1000 0.000003
shunt_zeroes: 10000 0.000018
shunt_zeroes: 100000 0.000155
RemoveDead: (Patrik)
RemoveDead: 100 0.000001
RemoveDead: 1000 0.000004
RemoveDead: 10000 0.000018
RemoveDead: 100000 0.000159
pushbackzeros2: (UmNyobe)
pushbackzeros2: 100 0.000001
pushbackzeros2: 1000 0.000005
pushbackzeros2: 10000 0.000031
pushbackzeros2: 100000 0.000449
list_compact: (Wildplasser)
list_compact: 100 0.000004
list_compact: 1000 0.000005
list_compact: 10000 0.000036
list_compact: 100000 0.000385
shufflezeroes: (Patrik)
shufflezeroes: 100 0.000003
shufflezeroes: 1000 0.000069
shufflezeroes: 10000 0.006685
shufflezeroes: 100000 0.504551
pushbackzeros: (UmNyobe)
pushbackzeros: 100 0.000003
pushbackzeros: 1000 0.000126
pushbackzeros: 10000 0.011719
pushbackzeros: 100000 0.480458
$
testzeromoves.c
)。算法实现位于顶部。测试工具在评论“测试工具”之后。该命令可以进行检查或计时或两者(默认);它默认进行两次迭代;默认情况下,它的大小可达一百万个条目。您可以使用
-c
省略检查的标志,
-t
标志省略计时,
-n
用于指定迭代次数的标志,以及
-m
标志来指定最大尺寸。过百万要谨慎;您可能会遇到 VLA(可变长度数组)炸毁堆栈的问题。修改代码以使用
malloc()
很容易和
free()
反而;不过,这似乎没有必要。
#include <string.h>
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
extern void shunt_zeroes(int *list, size_t n);
extern void pushbackzeros(int *list, size_t n);
extern void pushbackzeros2(int *list, size_t n);
extern void shufflezeroes(int *list, size_t n);
extern void RemoveDead(int *list, size_t n);
extern void list_compact(int *arr, size_t cnt);
void list_compact(int *arr, size_t cnt)
{
size_t dst,src,pos;
/* Skip leading filled area; find start of blanks */
for (pos=0; pos < cnt; pos++) {
if ( !arr[pos] ) break;
}
if (pos == cnt) return;
for(dst= pos; ++pos < cnt; ) {
/* Skip blanks; find start of filled area */
if ( !arr[pos] ) continue;
/* Find end of filled area */
for(src = pos; ++pos < cnt; ) {
if ( !arr[pos] ) break;
}
if (pos > src) {
memmove(arr+dst, arr+src, (pos-src) * sizeof arr[0] );
dst += pos-src;
}
}
}
/* Cannot change j to size_t safely; algorithm relies on it going negative */
void RemoveDead(int *list, size_t n)
{
int i, j = n - 1;
for (; j >= 0 && list[j] == 0; --j)
;
for (i = 0; i <= j; ++i)
{
if (list[i])
continue;
memcpy(&(list[i]), &(list[j]), sizeof(int));
list[j] = 0;
for (; j >= 0 && list[j] == 0; --j);
if (i == j)
break;
}
}
void shufflezeroes(int *list, size_t n)
{
for (size_t i = 0; i < n; ++i)
{
if (list[i])
continue;
size_t j;
for (j = i + 1; j < n && !list[j]; ++j)
;
size_t z;
for (z = j + 1; z < n && list[z]; ++z)
;
if (j == n)
break;
memmove(&(list[i]), &(list[j]), sizeof(int) * (z - j));
size_t s = z - j + i;
for(j = s; j < z; ++j)
list[j] = 0;
i = s - 1;
}
}
static int nextZero(int* list, size_t start, size_t n){
size_t i = start;
while(i < n && list[i])
i++;
return i;
}
static int nextNonZero(int* list, size_t start, size_t n){
size_t i = start;
while(i < n && !list[i])
i++;
return i;
}
void pushbackzeros(int* list, size_t n){
size_t i = 0;
size_t j = 0;
while(i < n && j < n){
i = nextZero(list,i, n);
j = nextNonZero(list,i, n);
if(i >= n || j >=n)
return;
list[i] = list[j];
list[j] = 0;
}
}
/* Amended algorithm */
void pushbackzeros2(int* list, size_t n){
size_t i = 0;
size_t j = 0;
while(i < n && j < n){
i = nextZero(list, i, n);
j = nextNonZero(list, MAX(i,j), n);
if(i >= n || j >=n)
return;
list[i] = list[j];
list[j] = 0;
}
}
void shunt_zeroes(int *list, size_t n)
{
if (n > 1)
{
size_t tail = n;
for (size_t i = 0; i < tail - 1; i++)
{
if (list[i] == 0)
{
while (--tail > i + 1 && list[tail] == 0)
;
if (tail > i)
{
int t = list[i];
list[i] = list[tail];
list[tail] = t;
}
}
}
}
}
/* Test Harness */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "timer.h"
#define DIM(x) (sizeof(x)/sizeof(*(x)))
typedef void (*Shunter)(int *list, size_t n);
typedef struct FUT /* FUT = Function Under Test */
{
Shunter function;
const char *name;
const char *author;
} FUT;
static int tflag = 1; /* timing */
static int cflag = 1; /* checking */
static size_t maxsize = 1000000;
static void dump_list(const char *tag, int *list, size_t n)
{
printf("%-8s", tag);
for (size_t i = 0; i < n; i++)
{
printf("%d ", list[i]);
}
putchar('\n');
fflush(0);
}
static void test_list(int *list, size_t n, Shunter s)
{
dump_list("Before:", list, n);
(*s)(list, n);
dump_list("After:", list, n);
}
static void list_of_tests(const FUT *f)
{
int list1[] = { 1, 0, 2, 0, 3, 0, 4, 0, 5 };
int list2[] = { 1, 2, 2, 0, 3, 0, 4, 0, 0 };
int list3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int list4[] = { 0, 1 };
int list5[] = { 0, 0 };
int list6[] = { 0 };
test_list(list1, DIM(list1), f->function);
test_list(list2, DIM(list2), f->function);
test_list(list3, DIM(list3), f->function);
test_list(list4, DIM(list4), f->function);
test_list(list5, DIM(list5), f->function);
test_list(list6, DIM(list6), f->function);
}
static void test_timer(int *list, size_t n, const FUT *f)
{
Clock t;
clk_init(&t);
clk_start(&t);
f->function(list, n);
clk_stop(&t);
char buffer[32];
printf("%-15s %7zu %10s\n", f->name, n, clk_elapsed_us(&t, buffer, sizeof(buffer)));
fflush(0);
}
static void gen_test(size_t n, const FUT *f)
{
int list[n];
for (size_t i = 0; i < n/2; i += 2)
{
list[2*i+0] = i;
list[2*i+1] = 0;
}
test_timer(list, n, f);
}
static void timed_run(const FUT *f)
{
printf("%s (%s)\n", f->name, f->author);
if (cflag)
list_of_tests(f);
if (tflag)
{
for (size_t n = 100; n <= maxsize; n *= 10)
gen_test(n, f);
}
}
static const char optstr[] = "cm:n:t";
static const char usestr[] = "[-ct][-m maxsize][-n iterations]";
int main(int argc, char **argv)
{
FUT functions[] =
{
{ shunt_zeroes, "shunt_zeroes:", "Jonathan" }, /* O(N) */
{ RemoveDead, "RemoveDead:", "Patrik" }, /* O(N) */
{ pushbackzeros2, "pushbackzeros2:", "UmNyobe" }, /* O(N) */
{ list_compact, "list_compact:", "Wildplasser" }, /* O(N) */
{ shufflezeroes, "shufflezeroes:", "Patrik" }, /* O(N^2) */
{ pushbackzeros, "pushbackzeros:", "UmNyobe" }, /* O(N^2) */
};
enum { NUM_FUNCTIONS = sizeof(functions)/sizeof(functions[0]) };
int opt;
int itercount = 2;
while ((opt = getopt(argc, argv, optstr)) != -1)
{
switch (opt)
{
case 'c':
cflag = 0;
break;
case 't':
tflag = 0;
break;
case 'n':
itercount = atoi(optarg);
break;
case 'm':
maxsize = strtoull(optarg, 0, 0);
break;
default:
fprintf(stderr, "Usage: %s %s\n", argv[0], usestr);
return(EXIT_FAILURE);
}
}
for (int i = 0; i < itercount; i++)
{
for (int j = 0; j < NUM_FUNCTIONS; j++)
timed_run(&functions[j]);
if (tflag == 0)
break;
cflag = 0; /* Don't check on subsequent iterations */
}
return 0;
}
关于c - 高效的列表压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12515755/
我有点想做 the reverse of this. 我不想解压缩并将收集文件添加到 S3 应用户要求: 生成一堆xml文件 使用一些图像(托管在 s3 上的预先存在的图像)压缩 xml 文件 下载
将此添加到域的虚拟主机后 AddOutputFilterByType DEFLATE application/javascript text/javascript text/css 响应头不包含任何内
在 Apache Im 中,通过将以下内容添加到我的 .htaccess 文件来启用输出压缩: # compress text, html, javascript, css, xml: AddOutp
是否可以以压缩格式将请求数据从浏览器发送到服务器? 如果是,我们该怎么做? 最佳答案 压缩从浏览器发送到服务器的数据是不受 native 支持 在浏览器中。 您必须找到一种解决方法,使用客户端语言(可
我正在寻找可以压缩JavaScript源代码的工具。我发现一些网络工具只能删除空格字符?但也许存在更好的工具,可以压缩用户的函数名称、字段名称、删除未使用的字段等。 最佳答案 经常用来压缩JS代码的工
使用赛马博彩场景,假设我有许多单独的投注来预测比赛的前 4 名选手 (superfecta)。 赌注如下... 1/2/3/4 1/2/3/5 1/2/4/3 1/2/4/5 1/2/5/3
我是一名实习生,被要求对 SQL 2008 数据压缩进行一些研究。我们想将 Outlook 电子邮件的几个部分存储在一个表中。问题是我们想将整个电子邮件正文存储在一个字段中,然后又想压缩它。使用 Ch
我目前有一个系统,用户可以在其中上传 MP4 文件,并且可以在移动设备上下载该文件。但有时,这些视频的大小超过 5MB,在我国,大多数人使用 2G。因此,下载大型视频通常需要 15-20 分钟。 有什
假设我有一个带有类型列的简单文档表: Documents Id Type 1 A 2 A 3 B 4 C 5 C 6 A 7 A 8 A 9 B 10 C 用户
我有一个较大字符串中的(子)字符串位置的 data.frame。数据包含(子)字符串的开头及其长度。可以很容易地计算出(子)字符串的结束位置。 data1 start length end #>
我想知道是否 文件加密算法可以设计成它也可以执行文件压缩的事件(任何活生生的例子?)。 我也可以将它集成到移动短信服务中,我的意思是短信吗? 另外我想知道二进制文件...如果纯文本文件以二进制编码
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我们有几个具有大量 JavaScript 的 Java 项目,目前我们使用的是旧版本的 YUICompressor (2.4.2)。然而,我在这篇博文中发现 YUICompressor 正在 depr
从之前关于尝试提高网站性能的文章中,我一直在研究 HTTP 压缩。我读过有关在 IIS 中设置它的信息,但它似乎是所有 IIS 应用程序池的全局事物,我可能不允许这样做,因为还有另一个站点在其上运行。
我有一个 REST 服务,它返回一大块 XML,大约值(value) 150k。 例如http://xmlservice.com/services/RestService.svc/GetLargeXM
我正在尝试获取一个简单的 UglifyJS (v2.3.6) 示例来处理压缩。 具体来说,“未使用”选项,如果从未使用过,变量和函数将被删除。 这是我在命令行上的尝试: echo "function
我正在开发一个项目,如果我的磁盘出现问题,我将在使用 ZLIB 压缩内存块后将其发送到另一个磁盘。然后我计划下载该转储并用于进一步调试。这种压缩和上传将一次完成一个 block - 比如说 1024
LZW 压缩算法在压缩后增加了位大小: 这是压缩函数的代码: // compression void compress(FILE *inputFile, FILE *outputFile) {
我的问题与如何在 3D 地形上存储大量信息有关。这些信息应该是 secret 的,因为它们非常庞大,也应该被压缩。我选择了文件存储,现在我想知道将对象数据加密/压缩(或压缩/加密)到文件的最佳做法。
我使用以下代码来压缩我的文件并且效果很好,但我只想压缩子文件夹而不是在压缩文件中显示树的根。 public boolean zipFileAtPath(String sourcePath, Strin
我是一名优秀的程序员,十分优秀!