我正在尝试编写一个 bool 函数来检查字符串输入是否有任何重复字符
I am trying to write a bool function that checks if the string input has any duplicate characters
我在main
下写了这个函数我想检查字符串输入是否有重复字符但是当我使用调试功能时结果发现外循环只循环一次而内循环正确循环.我不知道为什么外循环不应该迭代与字符串长度一样多的次数?,对不起,我 运行 进入另一个问题程序需要不区分大小写我尝试将 tolower 集成到bool 函数,但由于某种原因它不起作用,是的,它是一个 cs50 任务
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool only_letters(string s);
bool duplicts(string b);
int main(int argc, string argv[])
{
if(argc!=2){
printf("wrong input\n");
return 1;
}
int length=strlen(argv[1]);
if(length!=26){
printf("Key must contain 26 characters.\n");
return 1;
}
if(!only_letters(argv[1])){
printf("key must contain only alphapetic letters.\n");
return 1;
}
if(!duplicts(argv[1])){
printf("key must not contain same characters\n");
return 1;
}
}
// need a check input function if letters or not
bool only_letters(string s){
int length=strlen(s);
for(int i =0;i<length;i++){
if(!isalpha(s[i]))
return false;
}return true;
}
bool duplicts(string b) {
int length = strlen(b);
for (int i = 0; i < length; i++) {
for (int k = i + 1; k < length; k++) {
tolower(b[i]);
tolower(b[k]);
if (b[i] == b[k])
return false;
}
}
return true;
}
使用合理的缩进约定重新格式化代码会使错误变得显而易见:
bool duplicts(string b) {
int length = strlen(b);
int count = 0;
for (int i = 0; i < length; i++) {
for (int k = 1; k < length; k++) {
if ((b[i]) == b[k])
count++;
}
return count;
}
if (count > 0) {
return false;
}
return true;
}
return count;
在外层循环中,因此只迭代一次。
还有一个问题:内部循环应该从k = i + 1
开始,否则你总是会在超过1个字节的字符串中找到重复项。
只要发现重复字符,您的代码就可以轻松修改为 return false
:
bool duplicts(string b) {
int length = strlen(b);
for (int i = 0; i < length; i++) {
for (int k = i + 1; k < length; k++) {
if (b[i] == b[k])
return false;
}
}
return true;
}
您可以进一步简化以避免调用 strlen
并处理任意大字符串(尽管效率很低):
bool duplicts(const char *s) {
for (; *s != '[=12=]'; s++) {
for (size_t k = 1; s[k] != '[=12=]'; k++) {
if (s[k] == *s)
return false;
}
}
return true;
}
要修复对大字符串效率低下的二次复杂度,您可以使用数组:
bool duplicts(const char *s) {
unsigned char seen[256] = { 0 };
unsigned char c;
while ((c = *s++) != '[=13=]') {
if (seen[c] != 0)
return false;
seen[c] = 1;
}
return true;
}
我在main
下写了这个函数我想检查字符串输入是否有重复字符但是当我使用调试功能时结果发现外循环只循环一次而内循环正确循环.我不知道为什么外循环不应该迭代与字符串长度一样多的次数?,对不起,我 运行 进入另一个问题程序需要不区分大小写我尝试将 tolower 集成到bool 函数,但由于某种原因它不起作用,是的,它是一个 cs50 任务
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool only_letters(string s);
bool duplicts(string b);
int main(int argc, string argv[])
{
if(argc!=2){
printf("wrong input\n");
return 1;
}
int length=strlen(argv[1]);
if(length!=26){
printf("Key must contain 26 characters.\n");
return 1;
}
if(!only_letters(argv[1])){
printf("key must contain only alphapetic letters.\n");
return 1;
}
if(!duplicts(argv[1])){
printf("key must not contain same characters\n");
return 1;
}
}
// need a check input function if letters or not
bool only_letters(string s){
int length=strlen(s);
for(int i =0;i<length;i++){
if(!isalpha(s[i]))
return false;
}return true;
}
bool duplicts(string b) {
int length = strlen(b);
for (int i = 0; i < length; i++) {
for (int k = i + 1; k < length; k++) {
tolower(b[i]);
tolower(b[k]);
if (b[i] == b[k])
return false;
}
}
return true;
}
使用合理的缩进约定重新格式化代码会使错误变得显而易见:
bool duplicts(string b) {
int length = strlen(b);
int count = 0;
for (int i = 0; i < length; i++) {
for (int k = 1; k < length; k++) {
if ((b[i]) == b[k])
count++;
}
return count;
}
if (count > 0) {
return false;
}
return true;
}
return count;
在外层循环中,因此只迭代一次。
还有一个问题:内部循环应该从k = i + 1
开始,否则你总是会在超过1个字节的字符串中找到重复项。
只要发现重复字符,您的代码就可以轻松修改为 return false
:
bool duplicts(string b) {
int length = strlen(b);
for (int i = 0; i < length; i++) {
for (int k = i + 1; k < length; k++) {
if (b[i] == b[k])
return false;
}
}
return true;
}
您可以进一步简化以避免调用 strlen
并处理任意大字符串(尽管效率很低):
bool duplicts(const char *s) {
for (; *s != '[=12=]'; s++) {
for (size_t k = 1; s[k] != '[=12=]'; k++) {
if (s[k] == *s)
return false;
}
}
return true;
}
要修复对大字符串效率低下的二次复杂度,您可以使用数组:
bool duplicts(const char *s) {
unsigned char seen[256] = { 0 };
unsigned char c;
while ((c = *s++) != '[=13=]') {
if (seen[c] != 0)
return false;
seen[c] = 1;
}
return true;
}