【问题标题】:Convert string into three letter Abbreviation将字符串转换为三个字母的缩写
【发布时间】:2016-01-04 12:37:58
【问题描述】:

我最近接到了一个新项目,将任何给定的字符串转换为 1-3 个字母的缩写。 下面是一个类似于我必须产生的东西的例子,但是给出的字符串可以是任何东西:

switch (string.Name)
        {
            case "Emotional, Social & Personal": return "ESP";
            case "Speech & Language": return "SL";
            case "Physical Development": return "PD";
            case "Understanding the World": return "UW";
            case "English": return "E";
            case "Expressive Art & Design": return "EAD";
            case "Science": return "S";
            case "Understanding The World And It's People"; return "UTW";

}

我想我可以使用 string.Split 并计算数组中的单词数。然后添加处理特定长度字符串的条件,因为这些句子通常不会超过 4 个单词,但我会遇到的问题是。

  1. 如果一个字符串比我预期的长,它就不会被处理
  2. 必须从缩写中排除符号

任何关于我可以应用的逻辑的建议将不胜感激。 谢谢

【问题讨论】:

  • 你好像忽略了《Understanding the World》中的“the”,但是却没有忽略《Understanding The World And It's People》中的“The”,是不是大写的原因?此外,您是否期望一组给定的输入被缩写,正如您的switch 似乎表明的那样,或者您是否希望输入是动态的?如果是前者,你最好使用Dictionary
  • 我会 string.Split 一个空格。遍历每个结果字符串,将它们与排除列表进行比较。如果它们不在其中,请取该单词的第一个字母并将其大写并继续前进。注意:替换任何可能在名称“_”“-”中使用的字符。
  • @ChrisHandy 这不适用于第四个或最后一个示例,因为两者都有工作“the”,但只有一个作为“T”。
  • 是的,单词“the”由于大写而被忽略,输入将是动态的。我知道一些给定的字符串输入,该开关目前用作临时解决方案。 @juharr
  • 是的,但您可以使用 Hashmap 或类似的东西来存储排除项。这样你检查字符串 x 是否存在于 hashmap 中(不需要遍历所有内容),如果不存在,那么你知道它是一个应该缩写的词。

标签: c# arrays string split logic


【解决方案1】:

以下内容应该适用于您给出的示例。

string abbreviation = new string(
    input.Split()
          .Where(s => s.Length > 0 && char.IsLetter(s[0]) && char.IsUpper(s[0]))
          .Take(3)
          .Select(s => s[0])
          .ToArray());

您可能需要根据您的预期输入调整过滤器。可能会添加要忽略的单词列表。

【讨论】:

  • 谢谢,我可能会这样做
  • @juharr 非常简洁。 +10
【解决方案2】:

看来,如果没关系,你可以选择最简单的东西。如果字符串少于 4 个单词,则取每个字符串的第一个字母。 如果字符串长于 4,则消除所有“ands”和“ors”,然后执行相同操作。

为了更好,你可以有一个你不关心的词的查找字典——比如“the”或“so”。

您还可以按字母顺序保留一个 3D 字符数组,以便快速查找。这样一来,您就不会有任何重复的缩写词。

但是,只有有限数量的缩写。因此,最好将“无用”单词存储在另一个字符串中。这样,如果您的程序默认使用的缩写已经被使用,您可以使用无用的单词来制作一个新的。

如果以上所有方法都失败了,您可以开始线性移动字符串以获得不同的 3 字母单词缩写 - 有点像 DNA 上的密码子。

【讨论】:

  • 可能返回的值将存储在某个地方,因为我猜您还需要确保您不返回已使用的缩写。
  • 我可以应用该逻辑的大部分内容,除非在最后一种情况下,字符串是“Understanding The World And It's People”,最后一个词“People”可能比“The "
  • @LeonWinston 看起来您用于创建缩写的规则不一致
  • @LeonWinston 否则我有一个解决方案
  • 我也这么认为,我不知道我可以将哪些一致的规则应用于动态字符串的缩写,你有什么建议? @亚历克斯
【解决方案3】:

使用字典的完美场所

           Dictionary<string, string> dict = new Dictionary<string, string>() {
                {"Emotional, Social & Personal", "ESP"},
                {"Speech & Language","SL"},
                {"Physical Development", "PD"}, 
                {"Understanding the World","UW"},
                {"English","E"},
                {"Expressive Art & Design","EAD"},
                {"Science","S"},
                {"Understanding The World And It's People","UTW"}
            };

            string results = dict["English"];​

【讨论】:

  • 除非OP已经表明输入是动态的。
  • 哪里说的是动态的?以及如何确定要消除哪些单词,例如“the”、“and”、“it's”……如果您有一种算法可以消除所有不需要的单词,那么字典可以是动态的。
  • 将其粘贴到此处:“将任何给定字符串转换为”
  • 另外,如果您阅读了 cmets,我特别询问输入是否可以是动态的,并且 OP 回答了。
【解决方案4】:

以下 sn-p 可能会对您有所帮助:

string input = "Emotional, Social & Personal"; // an example from the question 
string plainText = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Regex.Replace(input, @"[^0-9A-Za-z ,]", "").ToLower()); // will produce a text without special charactors
string abbreviation = String.Join("",plainText.Split(" ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries).Select(y =>y[0]).ToArray());// get first character from each word

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多