排序数字(下划线)

时间:2013-08-25 13:25:37

标签: c algorithm data-structures

我正在努力解决我的最后一个问题,但我仍然无法弄清楚如何解决它。我的任务是编写一个对数字进行排序的程序,但是:我们的导师为程序处理数字提供了一些额外的分数,例如:000054667(实际上是54667)和345_845(实际上是345845)。第一个问题已经解决但我不知道如何处理第二个问题。因此,我的问题是:你有任何提示/线索,这可能对我有帮助吗?我也发送了我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NUMBER_CHUNK 13


char* getNumber(FILE* fp) 
{
    int length, c;
    int current=0;
    char *number;

    number=(char*)malloc(sizeof(char)*NUMBER_CHUNK);
    if(!number)
    {
        printf("Error while alocating memory!\n");
        return NULL;
    }

    length=NUMBER_CHUNK;

    while(!isspace(c=fgetc(fp)) && !feof(fp))
    {
        if(isdigit(c))
        {
            number[current]=c;
            current++;
            if(current>=length) 
            {
                length+=NUMBER_CHUNK;

                if((number=((char*)realloc(number,sizeof(char*)*length)))==NULL)
                {
                    free(number);
                    return NULL;
                }
            }   
        }

        else
        {
            return NULL;
        }
    }

    number[current]='\0';
    return number;
}

int compare( const void *str1, const void *str2)
{
    int value;
    char* curr1;
    char* curr2;

    curr1=*(char**)str1;
    curr2=*(char**)str2;

    while(*curr1=='0') curr1++; 
    while(*curr2=='0') curr2++;

    if(strlen(curr1) < strlen(curr2)) return -1;
    if(strlen(curr1) > strlen(curr2)) return 1;

    value=strcmp(curr1, curr2);

    return value;
}

int main(int argc, char** argv) 
{
    FILE* fp;
    char** tab;
    int i=0;
    int lines=0;
    int length=10;

    if(argc!=2)
    {
        printf("Incorrent syntax! Use ./name_of_program input_file\n");
        return 1;
    }

    if(!(fp=fopen(argv[1],"r")))
    {
        printf("Could not open the file! Please try again!\n");
        return 2;
    }

    tab = (char**)malloc(length*(sizeof(char*)));

    if(!tab)
    {
        printf("Could not allocate memory! Terminating...\n");
        free(tab);
        return 3;
    }

    while(!feof(fp))
    {
        tab[i]=getNumber(fp);



        if(i>=length) 
            {
                length+=10;

                if((tab=((char**)realloc(tab,sizeof(char*)*length)))==NULL)
                {
                    free(tab);
                    return 5;
                }
            }
        if(tab[i]==NULL)
        {
            printf("Incorrect character in the infile! Terminating\n");
            free(tab);
            return 4;
        }
        if(*tab[i]=='\0')
        {
            free(tab[i]);
            i--;
        }

        i++;
        lines++;
        lines=i;
    }
    printf("\nBEFORE\n");


    for(i=0;i<lines;i++)
    {
        printf("%s\n",tab[i]);
    }

    qsort(tab, lines, sizeof(char*), &compare);

    printf("\nAFTER\n");


    for(i=0;i<lines;i++)
    {
        printf("%s\n",tab[i]);
        free(tab[i]);
    }

    free(tab);
    fclose(fp);
    return 0;
}

感谢您的帮助;)

5 个答案:

答案 0 :(得分:0)

只需继续解析字符串,直到获得下划线,并且解析也会将每个字符转换为相应的数字,并根据它的位置值将其添加到新数字中(简而言之,我&#39;我说的是将字符串转换为数字的算法。

如果你遇到下划线,只需使用

  

继续;

答案 1 :(得分:0)

如果您想保留“数字”的字符串表示形式,但要根据它们的数值进行比较,请不要将它们作为compare函数中的字符串进行比较。

内部compare解析每个参数(str1str2)并将其转换为跳过前导零和下划线的数字。一旦有两个数字(比如num1num2),只需return num1 - num2

答案 2 :(得分:0)

不是存储一堆字符串,而是通过剥离任何非数字字符并在结果上调用atoi来将数字转换为整数。您可以将这些数字直接存储在数组中。然后compare函数变得更加简单。

答案 3 :(得分:0)

更改字符串累积和比较例程。

字符串累积:

if(isdigit(c) || (c == '_'))

进行比较。将值_忽略为价值评级时,这有点冗长。但它不限于适合任何int范围的数字。

 int compare(const void *str1, const void *str2) {
  const char* curr1 = *(const char**) str1;
  const char* curr2 = *(const char**) str2;
  // Remove leading zeros
  while ((*curr1 == '0') || (*curr1 == '_'))
    curr1++;
  while ((*curr2 == '0') || (*curr2 == '_'))
    curr2++;
  int value = 0;
  size_t len1 = 0;
  size_t len2 = 0;
  while (*curr1 || *curr2) {
    while (*curr1 == '_')
      curr1++;
    while (*curr2 == '_')
      curr2++;
    // If a difference has not been found yet ...
    if (value == 0) {
      value = *curr1 - *curr2;
    }
    if (*curr1) {
      curr1++;
      len1++;
    }
    if (*curr2) {
      curr2++;
      len2++;
    }
  }
  // If significant digits in string1 more than string2 ...
  if (len1 != len2) {
    return (len1 > len2) ? 1 : -1;
  }
  return value;
}

答案 4 :(得分:0)

chux THX。你太棒了!我希望我在编程方面能和你一样好。 我发送了我的整个(固定的,工作的)源代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NUMBER_CHUNK 13


char* getNumber(FILE* fp) 
{
    int length;
    int current = 0;
    int c;
    char *number, *number2;

    number = (char*)malloc(sizeof(char)*NUMBER_CHUNK);
    if(!number)
    {
        printf("Error while allocating memory!\n");
        return NULL;
    }

    length = NUMBER_CHUNK;

    while(!isspace(c = fgetc(fp)) && !feof(fp))
    {
        if(isdigit(c) || c == '_')
        {
            number[current] = c;
            current++;
            if(current >= length) 
            {

                length+=NUMBER_CHUNK;
                number2 = (char*)realloc(number,length*sizeof(char*));
                if(number2 == NULL)
                {
                    free(number2);
                    return NULL;
                }
                else number2 = number;
            }   
        }
        else
        {
            return NULL;
        }
    }

    number[current] = '\0';
    return number;
}

int compare(const void *str1, const void *str2)
{
    char* curr1;
    char* curr2;

    curr1=*(char**)str1;
    curr2=*(char**)str2;

    while(*curr1=='0' || *curr1=='_') curr1++; 
    while(*curr2=='0' || *curr2=='_') curr2++;

    int value = 0;
    size_t len1 = 0;
    size_t len2 = 0;

    while(*curr1 || *curr2)
    {
        while(*curr1 == '_')
            curr1++;
        while(*curr2 == '_')
            curr2++;

        if(value == 0)
        {
            value = *curr1 - *curr2;
        }
        if(*curr1)
        {
            curr1++;
            len1++;
        }
        if(*curr2)
        {
            curr2++;
            len2++;
        }
    }

    if(len1 != len2)
    {
        return (len1 > len2) ? 1 : -1;
    }

    return value;
}

int main(int argc, char** argv) 
{
    FILE* fp;
    char** tab;
    int i = 0;
    int lines = 0;
    int length = 10;

    if(argc != 2)
    {
        printf("Incorrent syntax! Use ./name_of_program input_file\n");
        return 1;
    }

    if(!(fp = fopen(argv[1],"r")))
    {
        printf("Could not open the file! Please try again!\n");
        return 2;
    }

    tab = (char**)malloc(length*(sizeof(char*)));
    if(!tab)
    {
        printf("Could not allocate memory!\n");
        free(tab);
        return 3;
    }

    while(!feof(fp))
    {
        tab[i] = getNumber(fp);

        if(i >= length) 
            {

                length += 10;
                tab = (char**)realloc(tab,sizeof(char*));
                if(tab == NULL)
                {
                    free(tab);
                    return 5;
                }
            }
        if(tab[i] == NULL)
        {
            printf("Incorrect character in the infile! Terminating\n");
            free(tab);
            return 4;
        }
        if(*tab[i] == '\0')
        {
            free(tab[i]);
            i--;
        }

        i++;
        lines = i;
    }

    printf("\nBEFORE\n");

    for(i = 0 ; i < lines; i++)
    {
        printf("%s\n", tab[i]);
    }

    qsort(tab, lines, sizeof(char*), compare);

    printf("\nAFTER\n");

    for(i = 0; i < lines; i++)
    {
        printf("%s\n",tab[i]);
        free(tab[i]);
    }
    printf("\n");
    free(tab);
    fclose(fp);
    return 0;
}