为了账号安全,请及时绑定邮箱和手机立即绑定

尝试删除字符时陷入无限循环

尝试删除字符时陷入无限循环

C#
慕的地6264312 2023-07-22 16:00:55
我正在开展一个项目,将英语翻译成猪拉丁语,以更好地学习字符串。我正在努力解决的规则是:如果单词以元音开头,只需在单词末尾添加 way 即可。如果单词以辅音开头,请将第一个元音之前的辅音移至单词末尾并添加 ay。我可以让元音起作用,但如果我达到一个常数,我就会陷入无限循环。我对编程相当陌生C#。任何解决这个问题的帮助将不胜感激,并希望能帮助我理解资源。我尝试过使用文本创建一个 char 并使用文本创建一个 int 来检查每个字母。不太确定该怎么做。这是翻译按钮代码:private void transBtn_Click(object sender, EventArgs e){    english = engTxtBx.Text;    english = english.Trim();    string[] columns = english.Split(' ');    for (int i = 0; i < columns.Length; i++)    {        string text = columns[i];        char first = text[0];        for (int c = 0; c < text.Length; c++)        {            char character = text[c];            //int consonant = text.IndexOf(character);            if (isVowel(first))            {                text = text + "way ";                pigLatin = text;                plTxtBx.Text += text;            }            else if (!isVowel(character))            {                if (isVowel(text[c + 1]))                {                    text.Remove(text.IndexOf(character), 1);                    text += character + "ay";                    pigLatin = text;                    plTxtBx.Text += text;                }                break;            }        }    }public static bool isVowel(char c){    return new[] {'a','e','i','o','u'}.Contains(char.ToLower(c));}如果我输入短语“Can I have an apple”,则应从第一个字符中删除“see”并移动到末尾,并在后面添加“ay”。现在,当我调试时,c 没有被删除,而是添加到末尾并添加了 ay。然后它就卡在了“我”上。
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

我做了一些更改以使其正常工作。请参阅我在代码中的注释。


private void transBtn_Click(object sender, EventArgs e)


{

    english = engTxtBx.Text;

    english = english.Trim();

    string[] columns = english.Split(' ');

    for (int i = 0; i < columns.Length; i++)

    {

        if (isVowel(columns[i][0]))

        {

            // Start with vowel.

            pigLatin = columns[i] + "way";

        }

        else

        {

            // Start with consonant. Get index of first vowel.

            int index = columns[i].IndexOfAny(vowels);

            if (index == -1)

            {

                // No vowel in columns[i].

                // You have to decide what to do.

            }

            else if (index == 1)

            {

                // First vowel is the second letter.

                pigLatin = columns[i].Substring(1) + columns[i][0] + "way";

            }

            else

            {

                // First vowel is after the second letter.

                pigLatin = columns[i].Substring(index) + columns[i].Substring(index - 1, 1) + "way";

            }


        }

        plTxtBx.Text += pigLatin;

    }


}


private static char[] vowels = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };


private static bool isVowel(char c)

{

    return vowels.Contains(c);

}


查看完整回答
反对 回复 2023-07-22
?
慕容708150

TA贡献1831条经验 获得超4个赞

所以罗伯特提供了一个修复程序,但既然你说你是编程新手,我将尝试解释这个问题,并且我将尝试用你正在做的事情的简化示例来实现:


string text = "Hello!";

for(int i = 0; i < text.Length; i++)

{

     text += "!";

}

您的循环条件基于 text.Length,但在循环内,您将附加到该文本,因此每次循环准备再次开始时,它都会检查 text.Length 并说:“好吧,我 - 仍然 - 不在 text.Length 的末尾,所以我想我会继续循环。


如果您只想根据初始字符数进行循环,您应该:


A. 在循环之前将 text.Length 存储到单独的变量中,然后将循环条件基于它,如下所示:


string text = "Hello!";

int initialLength = text.Length;

for(int i = 0; i < initialLength; i++)

{

     text += "!";

}

B. 或者更好的是,不要将更多内容附加到文本变量上,而是使用单独的字符串变量作为“修改后的”副本:


string text = "Hello!";

string text2 = text;

for(int i = 0; i < text.Length; i++)

{

     text2 += "!";

}

C. 或者最好采用方法 B,但使用 StringBuilder 类。在 C# 中,当您修改字符串时,系统会在内存中创建字符串的全新副本以及额外的字符,因此:


text = "Hello";

text += "!";

text += "!";

text += "!";

...实际上是在内存中创建四个不同的字符串变量:


你好你好!你好!!你好!!!


这是暂时的事情,但效率低且浪费。StringBuilder 类旨在允许您逐段高效地构建字符串:


StringBuilder sb = new StringBuilder("Hello");

sb.Append("!");

sb.Append("!");

sb.Append("!");

Console.WriteLine(sb.ToString()); // "Hello!!!"

因此,如果您查看示例 B,您可能会将其更改为:


string text = "Hello!";

StringBuilder sbText = new StringBuilder(text);

for(int i = 0; i < text.Length; i++)

{

     sbText.Append("!");

}

我的最终建议是也按照您想要的方式获取字符串/内容,然后将其分配给您的控件。所以不要调用这个 10 次:


 plTxtBx.Text += text;

相反,以正确的方式设置文本,然后在最后,只需做一个简单的分配:


 plTxtBx.Text = final_text;

原因是控件具有各种事件以及当您修改文本等属性时运行的小齿轮和齿轮。如果您使用 += 技巧将文本附加到 Textbox 控件,那么每次更新文本时都会强制该控件运行其整个例程。


这些都是很小的低效率问题,但随着时间的推移,它们会逐渐增加,因此最好提前做好这些工作。


因此,如果我采用罗伯特提出的代码(我没有亲自测试过)并对其进行一些更改,我会这样做:


private void transBtn_Click(object sender, EventArgs e)

{

    // Start with whatever is in plTxtBx

    StringBuilder sb = new StringBuilder(plTxtBx.Text); 


    // Break into words

    string[] columns = engTxtBx.Text.Trim().Split(' ');

    for (int i = 0; i < columns.Length; i++)

    {

        if (isVowel(columns[i][0]))

        {

            // Start with vowel.

            sb.Append(columns[i]);

            sb.Append("way");

        }

        else

        {

            // Start with consonant. Get index of first vowel.

            int index = columns[i].IndexOfAny(vowels);

            if (index == -1)

            {

                // No vowel in columns[i].

                // You have to decide what to do.

            }

            else if (index == 1)

            {

                // First vowel is the second letter.

                sb.Append(columns[i].Substring(1));

                sb.Append(columns[i][0]);

                sb.Append("way");

            }

            else

            {

                // First vowel is after the second letter.

                sb.Append(columns[i].Substring(index));

                sb.Append(columns[i].Substring(index - 1, 1));

                sb.Append("way");

            }


        }

    }


    // Update plTxtBx's Text once with the final results

    plTxtBx.Text = sb.ToString();


}


查看完整回答
反对 回复 2023-07-22
  • 2 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信