【问题标题】:Capitalize various letters in a string将字符串中的各种字母大写
【发布时间】:2016-08-08 19:02:58
【问题描述】:

我正在处理一个面试问题:

将字符串中的第 2、4、8、16 个字母大写

输入 - “字符串中的字母”

输出 - “字符串中的字母”

这是我的解决方案:

public static void main(String[] args) {
    String input = "letters in a string";

    String output = input.substring(0, 1) + input.substring(1, 2).toUpperCase() + input.substring(2, 3)
            + input.substring(3, 4).toUpperCase() + input.substring(4, 7) + input.substring(7, 8).toUpperCase()
            + input.substring(8, 15) + input.substring(15, 16).toUpperCase() + input.substring(15);
    System.out.println(output);

}

有没有什么方法可以在不硬编码偏移数字的情况下概括这一点?一般来说,我正在寻找的是 - 给定我们想要大写的字母数字,我们的程序应该在不改变核心逻辑的情况下工作,并且在复杂性方面也应该是高效的?

【问题讨论】:

  • 利用方法/功能
  • 如果可以的话,你面试什么工作不知道如何编写方法?
  • @JunedAhsan,但这里没有人有一个通用的Capitalize(String s, int index),另一种方法Capitalize(String s, int[] indices) 可以在循环中使用。实现非常简单的解决方案,非常可重用,非常简洁等。
  • @BenKnoble 并且方法名应该以小写开头。
  • 好点。我偶尔会滑倒(和大多数人一样)

标签: java string algorithm


【解决方案1】:

假设您想将角色设置为不断增加的幂范围 2(2、4、8、16、32、64...),您可以简单地使用循环。

问题是,String 不是可变的(无法更改),您应该尽可能避免在循环内连接String(好吧,在您的情况下,这可能不是什么大问题,但它是还是很好的做法)。

为此,您可以将 String 转换为 char 数组 (String#toCharArray()) 或使用 StringBuilder,例如...

String text = "letters in a string";
int index = 2;
StringBuilder sb = new StringBuilder(text);
while (index < sb.length()) {
    sb.setCharAt(index - 1, Character.toUpperCase(sb.charAt(index - 1)));
    index *= 2;
    System.out.println(index);
}

System.out.println(sb.toString());

哪个输出lEtTers in a stRing

【讨论】:

  • 击败我;不过我没想过这样跳到下一个索引。
【解决方案2】:

是的,您无需对偏移量进行硬编码即可执行此操作。这是一个例子:

int[] toCaps = new int[]{2, 4, 8, 16};
String input = "letters in a string";
String newString = "";
for(int i = 0; i < input.length(); i++){
    boolean b = false;
    for(int j : toCaps){
        if(i == (j-1)){//Subtract 1 since the indexing starts at 0.
            b = true;
        }
    }
    if(b){
        newString += Character.toUpperCase(input.charAt(i));
    }else{
        newString += input.charAt(i);
    }
}
System.out.println(newString);

现在 toCaps 数组中的数字将是转换为大写的字符串的位置。

【讨论】:

  • 循环连接? StringBuilder 会更好(虽然这里可能不是问题)
  • @BenKnoble 我对 StringBuilders 了解不多,所以我假设你是对的。我只是尽量避免进口。
  • 很公平。就像我说的,在这个微不足道的例子中,它不应该太重要。但一般来说,应避免在循环中连接。
  • @BenKnoble 可以通过创建一个 ArrayList 并改用 .contains 来避免循环,但我想在这种情况下它真的无关紧要。
  • 好收获。这就是我喜欢 StackOverflow 的原因:不同的解决方案
【解决方案3】:

也许你可以做类似的事情

public static String capitalize(String s, int[] array)//array would be the indexes you want to be caps.
{
  char[] stringChars = new char[s.length];
  for(int x = 0; x < stringChars.length; x++)
  {
    stringChars[x] = s.charAt(x);
  }
  String finalString;
  boolean matches;
  for(int x = 0; x < stringChars.length; x++)
  {
    for(int y = 0; y < array.length; y++)
    {
      if(array[y] == x)
        {
         matches = true;
         break;
        }
       if(matches == true)
         stringChars[x] = Character.toUppercase(stringChars[x]);
       finalString += stringChars[x];
    }
  }
  return finalString;
}

我没有测试过这段代码,可能有一些错误,但它可以工作。

【讨论】:

    【解决方案4】:

    正如其他人所说,最好的方法是编写一个可以多次使用的方法。试试这个:

    public static String capitalize(String string, int[] caps) {
        if (caps[caps.length - 1] > string.length()) {
            return "String not long enough.";
        }
        StringBuilder sb = new StringBuilder(string);
        for (int i : caps) {
            sb.setCharAt(i - 1, Character.toUpperCase(sb.charAt(i - 1)));
        }
        return sb.toString();
    }
    
    
    public static void main(String[] args) {
        int[] caps = {2, 4, 8, 16};
        System.out.println(capitalize("letters in a string", caps));
    }
    

    【讨论】:

    • @MadProgrammer 好吧,我们都建议了类似的解决方案,不管是哪种方式。
    • 那么为什么要重复已经建议的内容呢?我至少可以数出 3 种不同的方法。问题是,你的补充是什么,其他类似的答案没有
    • 首先,我建议使用一种他没有提到的方法。其次,它可能略有“相似”,但远非相同。
    【解决方案5】:

    这是我认为最好的方法:

    //here index is the nth letter to capitalize, i.e. 2 changes the character
    //at index 1, hence the subtraction
    public String capitalize(String s, int index)
    {
        StringBuilder sb = new StringBuilder(s);
        sb.setCharAt(index - 1, Character.toUpperCase(sb.charAt(index - 1)));
        return (sb.toString());
    }
    
    //indices in the array should the follow the same convention as above
    public String capitalize(String s, int[] indices)
    {
        for (int i = 0; i < indices.length; i++)
        {
            s = Capitalize(s, indices[i]);
        }
        return s;
    }
    

    从这里调用检索到的输入的方法很简单。

    编辑:返回随机查看此内容后,在循环中创建 StringBuilder 可能代价高昂,因为它仅在一个方法主体内有用。更好的方法是扩展模式以在方法中传递对字符串的 StringBuilder 引用(以某种私有方式),以避免一直创建新的。

    【讨论】:

      【解决方案6】:

      我更安全的实现:

      public static String toCapitalizedCase(String givenString) {
          if(TextUtils.isEmpty(givenString)){
              return givenString;
          }
          String[] arr = givenString.toLowerCase().split(" ");
          StringBuffer sb = new StringBuffer();
      
          for (int i = 0; i < arr.length; i++) {
              sb.append(Character.toUpperCase(arr[i].charAt(0)))
                      .append(arr[i].substring(1)).append(" ");
          }
          return sb.toString().trim();
      }
      

      【讨论】:

        猜你喜欢
        • 2021-01-06
        • 2015-05-11
        • 1970-01-01
        • 2012-02-17
        • 2016-02-15
        • 1970-01-01
        • 1970-01-01
        • 2019-06-08
        • 1970-01-01
        相关资源
        最近更新 更多