【问题标题】:Need algorithm to solve shifting in C [closed]需要算法来解决 C 中的移位问题
【发布时间】:2013-07-26 11:29:28
【问题描述】:
a.txt    
     #0   p0=1 p100=0 p4=0 p7=1
     #10  p5=1 p100=1 p8=0

如果我有一个文件名a.txt 并且我实际上要处理类似于班次特定px 之类的内容,例如如上所示p0,p1,p2。 例如,如果在我的命令行中将有开关来定义哪个px 需要由#shift_value 移动,例如

-shift p100=shift_value15:p5=shift_value4:p7=shift_value2

所以文件中的内容会改变如下:

a.txt(result)
         #0  p0=1 p4=0
         #2  p7=1
         #10 p8=0
         #14 p5=1
         #15 p100=0
         #25 p100=1

所以从开关到启用特定 px 的转移 #shift_value,当p100 位于#0 时,将移动15 变为#15,其中p100#10 将转移到#25 所以其余的像素都是一样的。

我需要一种算法来执行此行为,然后通过将 a.txt 中的内容转换为 a.txt(result)。

【问题讨论】:

  • 你到底想做什么?我不得不承认我不明白the algorithm to make the original a.txt without shifting to the shifted example是什么。
  • @Bentoy13 我的意思是我想让 a.txt 变成 a.txt(result)。我需要一种算法来进行转换,以动态方式获得我想要的结果。
  • 好吧,首先:你不是在这里移动,你是在“移动”。如果您刚刚告诉主题,您的问题对人们来说会更清楚,您想将某些px 定义移动一定数量的行,并且您的命令行开关告诉程序哪个px 定义应为moved向下多少行。我大概花了 5 分钟才弄清楚您要做什么,而您的描述并没有真正的帮助,我仅通过输入数据、输出数据和命令行开关才弄清楚。
  • 我不太明白你在寻找什么样的“算法”,这个任务对我来说看起来很原始。一种简单的方法似乎相当简单,或者您的文件是否包含数十万行,所以您需要比最简单的方法更快的方法?

标签: c


【解决方案1】:

像这样(省略错误处理,strtok_r如果可以使用则去掉strtok_r):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *strtok_r(char *str, const char *delims, char **store){
    char *p, *wk;
    if(str != NULL){
        *store = str;
    }
    if(*store == NULL) return NULL;
    *store += strspn(*store, delims);//skip delimiter
    if(**store == '\0') return NULL;
    p=strpbrk(wk=*store, delims);
    if(p != NULL){
        *p='\0';
        *store = p + 1;
    } else {
        *store = NULL;
    }
    return wk;
}

#define SHIFT_KEYWORD "shift_value"

typedef struct pair {
    char *key;
    int  val;
} Pair;

int cmp(Pair *a, Pair *b){
    return strcmp(a->key, b->key);
}

Pair *parse_command(const char *commands, int *num_cmd){
    char *pc, *cmd = strdup(commands);

    if(NULL!=(pc = strtok(cmd, " ")) && strcmp(pc, "-shift")!=0){
        fprintf(stderr, "command format error!\n");
        *num_cmd = 0;
        free(cmd);
        return NULL;
    }
    char *p;
    pc = strtok(NULL, " ");
    *num_cmd=1;
    for(p=pc;NULL!=(p=strchr(p, ':'));++p){
        ++*num_cmd;//count command
    }
    Pair *cmds = calloc(*num_cmd, sizeof(Pair));
    int c = 0;
    char *pr1, *pr2;
    for(p = pc;NULL!=(p=strtok_r(p, ":", &pr1));p=NULL){
        const int len = sizeof(SHIFT_KEYWORD)-1;
        for(;NULL!=(p=strtok_r(p, "=", &pr2));p=NULL){
            if(strncmp(p, SHIFT_KEYWORD, len)==0)
                cmds[c++].val = atoi(p + len);
            else
                cmds[c].key = strdup(p);
        }
    }
    qsort(cmds, *num_cmd, sizeof(Pair), (int (*)(const void*,const void*))cmp);
    free(cmd);
    return cmds;
}

int count_element(FILE *fp){
    int ch, count =0;
    while(EOF!=(ch=fgetc(fp))){
        if(ch == '=')
            ++count;
    }
    rewind(fp);
    return count;
}

typedef struct vec {
    int value;
    Pair pair;
} Vec;

int cmpv(const void *x, const void *y){
    Vec *a = (Vec*)x;
    Vec *b = (Vec*)y;
    return a->value != b->value ? a->value - b->value : strcmp(a->pair.key, b->pair.key);
}

int main(void){
    const char *command ="-shift p100=shift_value15:p5=shift_value4:p7=shift_value2";
    int num_cmd;
    Pair *cmd_list;

    cmd_list=parse_command(command, &num_cmd);

    FILE *fp=fopen("a.txt","r");
    int num_vec = count_element(fp);
    Vec v[num_vec];
    char buff[1024];
    int c=0;
    while(fgets(buff, sizeof(buff), fp)){
        char *p;
        int value;
        p=strtok(buff, " \n");
        if(*p == '#')
            value = atoi(p+1);
        else {
            fprintf(stderr, "data format error\n");
            exit(1);
        }
        for(;NULL!=(p=strtok(NULL, " \n"));++c){
            Pair *cmd;
            char *pr, *key;
            int event;
            pr=strchr(p, '=');
            *pr = '\0';
            key = strdup(p);
            event = atoi(pr+1);
            v[c].value = value;
            v[c].pair.key = key;
            v[c].pair.val = event;
            cmd = bsearch(&v[c].pair, cmd_list, num_cmd, sizeof(Pair), (int (*)(const void*,const void*))cmp);
            if(cmd){
                v[c].value = value + cmd->val;
            }
        }
    }
    fclose(fp);
    qsort(v, num_vec, sizeof(Vec), cmpv);

    //stdout -> fp = fopen("a.txt", "w");
    int i, pre_value=-1;
    for(i=0;i<num_vec;++i){
        if(pre_value != v[i].value){
            if(pre_value!=-1)
                fprintf(stdout, "\n");
            fprintf(stdout, "#%-2d", pre_value=v[i].value);
        }
        fprintf(stdout, " %s=%d", v[i].pair.key, v[i].pair.val);
        free(v[i].pair.key);
    }
    for(i=0;i<num_cmd;++i){
        free(cmd_list[i].key);
    }
    free(cmd_list);
    return 0;
}

【讨论】:

  • 感谢您提供这个。我从您的代码中得到了一些想法。非常感谢。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 2012-01-25
  • 2019-04-21
  • 1970-01-01
  • 2022-06-10
相关资源
最近更新 更多