程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在 C 中嵌套 for 和 if 循环大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决在 C 中嵌套 for 和 if 循环?

开发过程中遇到在 C 中嵌套 for 和 if 循环的问题如何解决?下面主要结合日常开发的经验,给出你关于在 C 中嵌套 for 和 if 循环的解决方法建议,希望对你解决在 C 中嵌套 for 和 if 循环有所启发或帮助;

我一直在学习哈佛的 CS50 课程,我有一个关于嵌套 for 和 if 循环的设计和使用的问题。我已经提交了一个问题集,现在我只是在进行“事后分析”,看看我是否可以更有效地编写它。特别是,我有一个函数,它接受 2 个参数:用户的一段文本和一个 26 个字母的密码密钥。然后通过将每个字符替换为相应的密钥值,将明文转换为密文。

我想知道我在这里写的方式是否会被认为是糟糕的设计?拥有多层 for 和 if 循环对我来说似乎很笨重。 (特别是遍历每个字符的字母字符串,然后将该字符重新分配给相应的密码密钥,似乎很复杂?)

谢谢,

// function for converTing plain text to cipher text
String substitution(String text,String cipher)
{
    String Alphabet = ("abcdefghijklmnopqrstuvwxyz");
    
    
    // for each character:
    for (int i = 0,n = strlen(text); i < n; i++)
    {
        // check if character is in the Alphabet:
        if ((text[i] >= 'a' && text[i] <= 'z') || (text[i] >= 'A' && text[i] <= 'Z'))
        {
            // find position in Alphabet by index,then convert to same index in the cipher String
            for (int j = 0; j < 26; j++)
            {
                if (text[i] == Alphabet[j])
                {
                    text[i] = cipher[j];
                    break;
                }
                if (text[i] + 32 == Alphabet[j])
                {
                    text[i] = cipher[j] - 32;
                    break;
                }
            }
        }
    }
    return text;
}

解决方法

您使用它来检查 text[i] 是否是字母表而不是 isalpha(),因此我假设您将程序的目标环境限制为字母表的字符代码是连续的(如 ASCII)。

        if ((text[i] >= 'a' && text[i] <= 'z') || (text[i] >= 'A' && text[i] <= 'Z'))

在此限制下,您可以简单地减去 'a''A' 来获取字符的索引,而无需使用循环来查找字符。

这意味着内循环部分

            for (int j = 0; j < 26; j++)
            {
                if (text[i] == alphabet[j])
                {
                    text[i] = cipher[j];
                    break;
                }
                if (text[i] + 32 == alphabet[j])
                {
                    text[i] = cipher[j] - 32;
                    break;
                }
            }

可以写成

            if (text[i] >= 'a' && text[i] <= 'z')
            {
                text[i] = cipher[text[i] - 'a'];
            }
            else
            {
                text[i] = cipher[text[i] - 'A'] - 32;
            }
,

您可以使用 strchr 函数压缩字符搜索,它的作用与您所做的相同。那里的效率提升不大。

要计算指数,您可以使用直接减法:

// check if character is in the alphabet:
if ((text[i] >= 'a' && text[i] <= 'z') {
    j = text[i]-'a';
    text[i] = cipher[j];
} else if ((text[i] >= 'A' && text[i] <= 'Z') {
    j = text[i]-'A';
    text[i] = cipher[j] + 32;
}

您还可以预先计算一个包含所有 255 个可能的字符值(不包括零)的表,如果字符不能被加密,则将值设置为零,否则设置密码值。

那么:

for (i = 0; text[i]; i++) {
    if (table[text[i]]) {
        text[i] = table[text[i]];
    }
}

当然,如果您需要对长文本进行加密,这是有道理的,否则您在计算表格上的花费比使用表格花费的要多。

此外,由于分支在许多架构上比简单分配更昂贵,请虑 MikeCAT 的绝妙建议,即“非密码”字符由自身替换,这样 text[i] = table[text[i]] 实际上什么都不做:

for (i = 0; text[i]; i++) {
    text[i] = table[text[i]];
}
,

这应该会更容易一些

String substitution(String text,String cipher)
{    
    // for each character:
    for (int i = 0,n = strlen(text); i < n; i++)
    {
        // check if character is in the alphabet:
        if (text[i] >= 'a' && text[i] <= 'z') 
        {
            text[i] = cipher[text[i] - 97]; // index of 'a' in alphabet is 97
        }
        else if (text[i] >= 'A' && text[i] <= 'Z'))
        {
            text[i] = cipher[text[i] - 65] - 32; // index of 'A' in alphabet is 65
        }
    }
    return text;
}
,

如果您要对字符代码顺序和关系(例如大写/小写转换)做出假设,那么 alphabet 数组几乎没有用处。它的唯一目的是将代码与平台定义的字符集排序分离。

在实践中,您的假设对于您可能遇到的任何平台都有效,这可能是一个公平的赌注,但如果您要定义 alphabet,那么您或许应该保持一致并编写其余代码独立于平台字符集。为此,您应该使用 ctype.h 标头。下面的代码做到了这一点,并且还消除了一些其他问题,例如“幻数”。

#include <String.h>
#include <ctype.h>
#include <stdbool.h>

// function for converTing plain text to cipher text
String substitution(String text,String cipher)
{
    static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
    static const size_t ALPHABET_LEN = sizeof(alphabet) / sizeof(*alphabet) ;
    
    // for each character:
    size_t text_len = strlen( text ) ;
    for( int i = 0; i < text_len; i++ )
    {
        // check if character is in the alphabet:
        if( isalpha( text[i] ) )
        {
            // find position in alphabet by index,then convert to same index in the cipher String
            for (int j = 0; j < ALPHABET_LEN; j++)
            {
                bool is_upper = isupper( text[i] ) ;
                if( !is_upper && text[i] == alphabet[j])
                {
                    text[i] = cipher[j];
                    break;
                }
                else if( is_upper && tolower(text[i]) == alphabet[j])
                {
                    text[i] = toupper( cipher[j] ) ;
                    break;
                }
            }
        }
    }
    
    return text;
}

这可能是一个见仁见智的问题,但许多编码标准只允许将 break 作为 switch-case 分隔符。用于中止循环的 breakconTinue 可能会创建糟糕且混乱的结构和控制流,并且可能使调试更加复杂,因为控制流可以“跳过”断点。避免使用break

        bool match = false ;
        for (int j = 0; !match && j < ALPHABET_LEN; j++)
        {
            bool is_upper = isupper( text[i] ) ;
            if( !is_upper && text[i] == alphabet[j])
            {
                text[i] = cipher[j];
                match = true ;
            }
            else if( is_upper && tolower(text[i]) == alphabet[j] )
            {
                text[i] = toupper( cipher[j] ) ;
                match = true ;
            }
        }

大佬总结

以上是大佬教程为你收集整理的在 C 中嵌套 for 和 if 循环全部内容,希望文章能够帮你解决在 C 中嵌套 for 和 if 循环所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。