cs50x 2020 - pset2 - 替换 - 键中的重复字符
cs50x 2020 - pset2 - substitution - duplicate characters in key
在检查我的代码以解决 2020 年 cs50 课程的 pset2 中的替换问题时,我一直在处理键中的重复字符时出错。我的代码和更多详细信息如下 - 谁能帮忙解决这个问题?谢谢
它给我的错误信息是
:( handles duplicate characters in key
timed out while waiting for program to exit
当我检查我的代码是否有重复字符时,它似乎工作正常(打印用法:./substitution key 并结束程序)
下面的代码
# include <stdio.h>
# include <cs50.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
int main(int argc, string argv[])
{
// Check that only one argument submitted
if (argc == 2)
{
// Check that key contains 26 characters
int keylen = strlen(argv[1]);
if (keylen == 26)
{
// Check that all characters are letters
for (int i = 0; i < keylen; i++)
{
bool lettercheck = isalpha(argv[1][i]);
if (lettercheck == true)
{
// THIS IS CAUSING ERROR - Check that no letters have been repeated - put all in lowercase to do so
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1][i - 1];
if (tolower(currentletter) == tolower(previousletter))
{
printf("Usage: ./substitution key\n");
return 1;
}
}
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
}
}
else
{
printf("Key must contain 26 characters.\n");
return 1;
}
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
// Get user input
string input = get_string("plaintext: ");
//Transform input using key
for(int i = 0; i < strlen(input); i++)
{
char currentletter = input[i];
int testlower = islower(currentletter);
int testupper = isupper(currentletter);
if (testupper > 0)
{
int j = input[i] - 65;
input[i] = toupper(argv[1][j]);
}
else if (testlower > 0)
{
int j = input[i] - 97;
input[i] = tolower(argv[1][j]);
}
}
printf("ciphertext: %s\n", input);
}
编辑:
找到解决方案 - 问题是第二个 for 循环针对 i - 1 次而不是 n 次
进行迭代
代码应该是
charpreviouslletter = argv[1][n]
而不是
charpreviousletter = argv[1][i - 1]
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1]**[i - 1]**
在这个循环中-
// THIS IS CAUSING ERROR - Check that no letters have been repeated - put all in lowercase to do so
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1][i - 1];
if (tolower(currentletter) == tolower(previousletter))
{
printf("Usage: ./substitution key\n");
return 1;
}
}
您只是将当前字符与前一个字符进行比较。这不适用于 abcdefca
这样的字符串
请注意,c
和 a
如何有重复项 - 但它们不在原件旁边,因此您的逻辑不会找到这些重复项。您的逻辑仅适用于彼此相邻的重复项,例如 aabcddef
.
相反,您需要记下循环时遇到的字符。如果您遇到一个您已经遇到过的角色,您就知道存在重复。
值得庆幸的是,密钥预计只包含字母表中的所有 26 个字符,没有任何重复。这意味着您可以简单地拥有一个包含 26 个槽的 int
数组——每个槽计算字母在该索引处出现的次数。第 0 个索引代表 'a',第一个索引代表 'b',依此类推。
这样,您可以使用 letter - 'a'
非常轻松地获取字母字符的索引,其中 letter
是字母字符。所以如果 letter
是 a
,你会得到 0,这确实是 'a'
的索引
另外,你在遍历键的时候有一个嵌套循环,这个嵌套循环也遍历了键。除了它只在某个索引之前这样做,该索引是外循环的当前索引。这看起来既浪费又奇怪。为什么不简单地循环一次,检查当前字符是否是字母和 还要检查以前是否遇到过这个字母。这就是您要做的全部!
int letter_presence[26];
char upperletter;
string key = argv[1];
if (strlen(key) == KEY_LEN)
{
for (int index = 0; index < KEY_LEN; index++)
{
if (!isalpha(key[index]))
{
// Wrong key - invalid character
printf("Usage: ./substitution key\n");
return 1;
}
if (letter_presence[tolower(key[index]) - 'a'] == 0)
{
// This letter has not been encountered before
letter_presence[upperletter - 'A'] = 1;
}
else
{
// Wrong key - Duplicate letters
return 1;
}
}
// All good
}
在检查我的代码以解决 2020 年 cs50 课程的 pset2 中的替换问题时,我一直在处理键中的重复字符时出错。我的代码和更多详细信息如下 - 谁能帮忙解决这个问题?谢谢
它给我的错误信息是
:( handles duplicate characters in key
timed out while waiting for program to exit
当我检查我的代码是否有重复字符时,它似乎工作正常(打印用法:./substitution key 并结束程序)
下面的代码
# include <stdio.h>
# include <cs50.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
int main(int argc, string argv[])
{
// Check that only one argument submitted
if (argc == 2)
{
// Check that key contains 26 characters
int keylen = strlen(argv[1]);
if (keylen == 26)
{
// Check that all characters are letters
for (int i = 0; i < keylen; i++)
{
bool lettercheck = isalpha(argv[1][i]);
if (lettercheck == true)
{
// THIS IS CAUSING ERROR - Check that no letters have been repeated - put all in lowercase to do so
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1][i - 1];
if (tolower(currentletter) == tolower(previousletter))
{
printf("Usage: ./substitution key\n");
return 1;
}
}
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
}
}
else
{
printf("Key must contain 26 characters.\n");
return 1;
}
}
else
{
printf("Usage: ./substitution key\n");
return 1;
}
// Get user input
string input = get_string("plaintext: ");
//Transform input using key
for(int i = 0; i < strlen(input); i++)
{
char currentletter = input[i];
int testlower = islower(currentletter);
int testupper = isupper(currentletter);
if (testupper > 0)
{
int j = input[i] - 65;
input[i] = toupper(argv[1][j]);
}
else if (testlower > 0)
{
int j = input[i] - 97;
input[i] = tolower(argv[1][j]);
}
}
printf("ciphertext: %s\n", input);
}
编辑: 找到解决方案 - 问题是第二个 for 循环针对 i - 1 次而不是 n 次
进行迭代代码应该是
charpreviouslletter = argv[1][n]
而不是
charpreviousletter = argv[1][i - 1]
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1]**[i - 1]**
在这个循环中-
// THIS IS CAUSING ERROR - Check that no letters have been repeated - put all in lowercase to do so
for (int n = 0; n < i; n++)
{
char currentletter = argv[1][i];
char previousletter = argv[1][i - 1];
if (tolower(currentletter) == tolower(previousletter))
{
printf("Usage: ./substitution key\n");
return 1;
}
}
您只是将当前字符与前一个字符进行比较。这不适用于 abcdefca
请注意,c
和 a
如何有重复项 - 但它们不在原件旁边,因此您的逻辑不会找到这些重复项。您的逻辑仅适用于彼此相邻的重复项,例如 aabcddef
.
相反,您需要记下循环时遇到的字符。如果您遇到一个您已经遇到过的角色,您就知道存在重复。
值得庆幸的是,密钥预计只包含字母表中的所有 26 个字符,没有任何重复。这意味着您可以简单地拥有一个包含 26 个槽的 int
数组——每个槽计算字母在该索引处出现的次数。第 0 个索引代表 'a',第一个索引代表 'b',依此类推。
这样,您可以使用 letter - 'a'
非常轻松地获取字母字符的索引,其中 letter
是字母字符。所以如果 letter
是 a
,你会得到 0,这确实是 'a'
另外,你在遍历键的时候有一个嵌套循环,这个嵌套循环也遍历了键。除了它只在某个索引之前这样做,该索引是外循环的当前索引。这看起来既浪费又奇怪。为什么不简单地循环一次,检查当前字符是否是字母和 还要检查以前是否遇到过这个字母。这就是您要做的全部!
int letter_presence[26];
char upperletter;
string key = argv[1];
if (strlen(key) == KEY_LEN)
{
for (int index = 0; index < KEY_LEN; index++)
{
if (!isalpha(key[index]))
{
// Wrong key - invalid character
printf("Usage: ./substitution key\n");
return 1;
}
if (letter_presence[tolower(key[index]) - 'a'] == 0)
{
// This letter has not been encountered before
letter_presence[upperletter - 'A'] = 1;
}
else
{
// Wrong key - Duplicate letters
return 1;
}
}
// All good
}