尝试输出此功能时,我什么也没\\空白

时间:2018-10-23 07:54:23

标签: c string function pointers char

更新“他的问题是让我只通过str运行一次,他们已经给我该函数只需要一个参数)”  我试图返回不重复自身的第一个字符,例如:“ blazqnqbla”->不重复自身的第一个字符为“ z”,因此该函数需要返回z。现在,该函数采用从字符构建的字符串(str),该字符的ASCII值在1-127(包括1和127)之间。 问题是我得到空白输出。尝试输出代码时我一无所获

#include <stdio.h>
char first(char *str);
char first(char *str){
    int L = 0;
    int a[127] = {0};
    for (int i=0; i<127; i++){
        a[i] = i+1;
    }
    while (str[L] != '\0'){
        for(int d=1; d<127; d++){
            if (str[L]==(char)d){
                if (a[L]>0){
                    a[L] = 0;
                    L++;
                    break;
                }
                else if (a[L]==0){
                    a[L] =- 1;
                    L++;
                    break;
                }
                else{
                    L++;
                    break;
                }
            }
        }
    }
    for (int i=0; i<127; i++){
        if(a[i]==0)
            return (char)(i+1);
    }
    return '\0';
}

int main()
{
    char s[] = "blazqnqbla";
    char m   = first(s);
    printf("%c", m);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

很抱歉,您的功能太复杂了。甚至您无法理解它,并在应该使用a[L]时使用a[d]。那将返回某些内容,但仅返回字母顺序的第一个字母。因此,在您的示例中为n

要使其正常运行,您需要:

  • 所有可能出现的字符的数组,以表示它们从未出现过(例如0),一次(例如> 0)或一次以上(例如-1)。
  • 一个数组,记录遇到唯一字符的顺序
  • 第一次遇到字符时,将其添加到数组中顺序的下一个位置,然后将该排名存储在第一个数组中。

该功能的代码可以变成:

char first(char *str){
    int a[127] = {0};              // rank+1 of the character in resul array
    char resul[127] = {0};         // array of candidates for unique characters
    int rank = 0;                  // current position in array of unique candidates
    char c;
    while((c = *str++) != '\0') {  // scan the input string one char at a time
        int i = (unsigned char) c; // convert to int to avoid warnings when
                                   //  using the char value as an index
        if (c > 127) {             // control char validity
            fprintf(stderr, "Forbidden character %d\n", i);
            return 1;
        }
        if (a[i] == 0) {        // first time seen, store the character
            resul[rank] = c;
            a[i] = rank + 1;    // and its rank
            rank += 1;
        }
        else if (a[i] > 0) {    // already seen, remove it
            resul[a[i] -1] = 0;
            a[i] = -1;          // and never use it any longer
        }
    }
    for(int i=0; i<127; i++){   // return first unique character
        if(resul[i]!=0)
            return resul[i];
    }
    return '\0';
}

在此代码中,输入字符串和结果数组仅被扫描一次。其他所有访问都直接通过索引进行。

答案 1 :(得分:1)

@Broman的实现是好的并且是递归的。 我包括一个非递归实现。 算法:从头到尾扫描字符串: 如果当前字符的索引从开头(strchr)和结尾(strrchr)相同,则该字符是唯一的。 否则,如果没有独特之处,我将返回“-”。 (这可能必须根据您的应用程序进行更改)


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

char first_unique_char(const char* s);

int main()
{
    char s[] = "abcdefghijtkqyabcdefghijkqx";
    char unique = first_unique_char(s);
    printf("The first unique char is %c\n",
                unique);
    return EXIT_SUCCESS;
}
// -----------------------------
char first_unique_char(const char* s)
{
    int i = 0;
    char* loc_forward = NULL;
    char* loc_backward = NULL;
    int len = strlen(s);
    bool found = false;

    printf("Len = %d\n", len);
    for(; i < len; i++)
    {
        loc_backward = strrchr(s, s[i]);
        loc_forward = strchr(s, s[i]);

        printf("i = %d, Char = %c, Loc_rev: %d, Loc_forward %d\n",
                        i, s[i], (int)(loc_backward - s), (int)(loc_forward - s));
        if ((loc_backward - s == i) && (loc_forward - s == i))//unique
        {
            found = true;
            break;
        }
    }
    printf("Returning at %d, s[i] = %c\n", i, s[i]);
    if (!found)
        return '-';
    else
        return s[i];
}

输出:

Len = 27
i = 0, Char = a, Loc_rev: 14, Loc_forward 0
i = 1, Char = b, Loc_rev: 15, Loc_forward 1
i = 2, Char = c, Loc_rev: 16, Loc_forward 2
i = 3, Char = d, Loc_rev: 17, Loc_forward 3
i = 4, Char = e, Loc_rev: 18, Loc_forward 4
i = 5, Char = f, Loc_rev: 19, Loc_forward 5
i = 6, Char = g, Loc_rev: 20, Loc_forward 6
i = 7, Char = h, Loc_rev: 21, Loc_forward 7
i = 8, Char = i, Loc_rev: 22, Loc_forward 8
i = 9, Char = j, Loc_rev: 23, Loc_forward 9
i = 10, Char = t, Loc_rev: 10, Loc_forward 10
Returning at 10, s[i] = t
The first unique char is t

Process returned 0 (0x0)   execution time : 0.016 s
Press any key to continue.

答案 2 :(得分:0)

您使它变得太复杂了。可以做到:

int in(char c, char *str) 
{
    while(*str != '\0') {
        if(*str == c)
            return 1;
        str++;
    }
    return 0;
}

char first(char *str)
{
    if(*str == '\0')
        return 0;
    else if(!in(*str, str+1))
        return *str;
    else return first(str+1);
}

in是一个辅助函数,如果字符串1包含字符str,则返回c

first将检查字符串中是否存在第一个字符。如果不是,那么我们找到了第一个非重复字符。如果没有,我们执行相同的过程,但是从字符串中的下一个字符开始。