我正在解决一个编程测验,我无法理解这段代码第10行背后的逻辑

时间:2016-08-31 05:35:44

标签: c algorithm

这是一个codechef测验。第一行输入已知的字母。第二个输入接收输入的数量,对于稍后给出的每个单词,我们必须执行操作,无论字符串是否可以由已知字母生成。我无法理解为什么在line 10中索引为s[i]-97的整数数组latin被赋值为1.有人可以解释吗?

int main(void) 
{

    int latin[26] = {0};
    int n, i, j, flag;
    char s[26], w[12];

    scanf ("%s", s);
    for (i=0; i<strlen(s); i++)
    latin[s[i]-97] = 1;

    scanf ("%d", &n);
    for (i=0; i<n; i++)
    {
        scanf ("%s", w);
        flag = 0;
        for (j=0; j<strlen(w); j++)
        {
            if (latin[w[j]-97] != 1)
            {
                printf ("No\n");
                flag = 1;
                break;
            }
        }

        if (flag == 0)
        printf ("Yes\n");
    }
    return 0;
} 

5 个答案:

答案 0 :(得分:1)

latin是一个数组,告诉我信件是否已知。例如:

latin[0] == 1; //letter 'a' is known
latin[3] == 0; //letter 'd' is unknown

最初,所有字母都是未知的。如果是字母&#39; d&#39;众所周知:

latin['d'-97] = 1; //letter 'd' is set to be known
//'d' has the ascii value of 100, thus 'd' - 97 equals 3.

要检查字符串w是否有效,程序会遍历字符串中的每个字母,如果有一个未知的字母,则该字符串无效。

答案 1 :(得分:0)

97是字母a的ASCII码,所以删除97后会将a转换为0,b转换为1等...

如果你询问作业,那就是要与之比较的值 latin[w[j]-97] != 1

答案 2 :(得分:0)

假设你输入&#34; abcd&#34;,那就变成了&#39;

这封信&#39; a&#39;在ascii表中是97。 所以&#39; a&#39; - 97 = 0,&#39; b&#39; - 97 = 1等。

拉丁语[0],拉丁语[1],拉丁语[2],拉丁语[3]都变为1,这意味着你输入的是&#39; a&#39;&#39; b&#39; &#39; c&#39;,&#39; d&#39; ..

然后在w中输入一个新字符串,下一个for循环检查新输入的字符是否输入到&#39; s&#39;太

for (j=0; j<strlen(w); j++)
  if (latin[w[j]-97] != 1) // here!

因此,如果您第二次输入bcda将打印&#34;是&#34;但如果您输入bbcd或abee,它将打印&#34; no&#34;因为你输入了至少一个不同的字符

答案 3 :(得分:0)

acually长度为h的元素将元素存储在0到n-1的位置。从a到z有26个字符。你声明数组

 int latin[26] = {0}; 

表示拉丁语的大小为26,在0到25的位置为0。

 for (i=0; i<strlen(s); i++)
 latin[s[i]-97] = 1;

拉丁语[s [i] -97] = 1的moto我们要考虑字母代表位置0,字母b代表位置1,依此类推......字母z代表位置z;

你所拉丁的所有角色都包含1个; 执行此循环后。

然后你正在阅读另一个单词并逐个选择每个字符,如果值不等于零,则检查该字符所代表的位置值是否意味着没有。所有单词的所有字符的值都等于yes然后flag将是价值1意味着我们会得到肯定。

答案 4 :(得分:0)

设计理念似乎是使用latin数组作为标志数组。也就是说 - latin中的每个元素都会告诉您特定字母是否是第一个输入字符串的一部分。

int latin[26] = {0};   // Initialize all elements to zero

scanf ("%s", s);       // Read a string (and pray that input is only letters)

for (i=0; i<strlen(s); i++)
     latin[s[i]-97] = 1;    // Set the flags to 1 for each input letter, i.e.
                            // if input contains 'a' latin[0] becomes 1
                            // if input contains 'b' latin[1] becomes 1
                            // and so on

所以这个想法似乎是在循环之后,你可以使用latin来知道输入中存在哪些字母。例如 - 如果latin[3]仍为0,则表示输入中没有c

代码充满了潜在的UB,需要重大改写。

一个例子:

scanf ("%s", s);             // Potential overflow -> may cause UB
for (i=0; i<strlen(s); i++)
    latin[s[i]-97] = 1;      // s[i] may be less than 97 -> UB
                             // s[i] may be greaterthan than 122 -> UB

至少解决它:

scanf ("%25s", s);           // Set upper limit for characters read
for (i=0; i<strlen(s); i++)
    if (s[i] >= 97 && s[i] <= 122) // Check before use
        latin[s[i]-97] = 1;
    else
        // Error handling (or just ignore)