【问题标题】:How to replace a char in a string without using Replace() in Java?如何在不使用 Java 中的 Replace() 的情况下替换字符串中的字符?
【发布时间】:2016-01-27 21:52:34
【问题描述】:

我在完成这项任务时遇到了问题:

给定一个字符串,将第一次出现的“a”替换为“x”,第二次出现的“a”替换为“xx”,第三次出现的“a”替换为“xxx”。第三次出现后,以“x”、“xx”、“xxx”……等重新开始替换模式;但是,如果一个 'a' 后面连续有 2 个以上的其他 'a' 字符,则不要替换该 'a' 之后的任何更多 'a' 字符。

不允许使用替换方法。

aTo123X("ababba") → "xbxxbbxxx"

aTo123X("anaceeacdabnanbag") → "xnxxceexxxcdxbnxxnbxxxg"

aTo123X("aabaaaavfaajaaj") → "xxxbxxxaaavfaajaaj"

aTo123X("pakaaajaaaamnbaa") → "pxkxxxxxxjxxaaamnbaa"

aTo123X("aaaak") → "xaaak"

我的代码输出包含 a,添加了 x,但 x 的数量不正确。


public String aTo123X(String str) {
  /*
  Strategy: 
  get string length of the code, and create a for loop in order to find each individual part of the String chars.check for a values in string and take in pos of the a.
  if one of the characters is a
    replace with 1 x, however, there aren't more than 2 a's immediately following first a and as it keeps searching through the index, add more x's to the original string, but set x value back to 1 when x reaches 3.
    if one of characters isn't a,
    leave as is and continue string.
  */

  String xVal = "";
  String x = "x";
  String output = "";
  for (int i = 0; i < str.length(); i++){

    if( str.charAt(i) == 'a'){
       output += x; 
       str.substring(i+1, str.length());
    }
    output += str.charAt(i);
  }
  return output;
}

【问题讨论】:

  • 有什么问题?
  • @MarounMaroun 当我返回它时,它不会删除 a,而只是添加 x,而且太多了
  • @Shivam 这里,'a' 之后不需要发生任何变化是 'aaa' 第一次出现的第一个 'a'。只需再仔细阅读您的评论一次,您就会明白。

标签: java regex string char


【解决方案1】:

首先,字符串是不可变的,所以下面的语句什么都不做

str.substring(i+1, str.length());

我猜你想这样做:

str = str.substring(i+1, str.length());

但是,即使修复了该问题,您的程序仍然无法运行。我无法真正理解您的解决方案。 1)您没有连续检测到超过 3 个 a。 2)你根本没有附加“xx”或“xxx”

这是我的版本,目前对我有用:

public static void main(String[] args) {
    System.out.println(aTo123X("ababba")); // "xbxxbbxxx"

    System.out.println(aTo123X("anaceeacdabnanbag")); // "xnxxceexxxcdxbnxxnbxxxg"

    System.out.println(aTo123X("aabaaaavfaajaaj")); // "xxxbxxxaaavfaajaaj"
}

public static String aTo123X(String str) {
    String output = "";
    int aOccurrence = 0;
    String[] xs = {"x", "xx", "xxx"};
    for (int i = 0; i < str.length(); ++i) {
        if (str.charAt(i) == 'a') {
            output += xs[aOccurrence % 3]; // append the x's depending on the number of a's we have seen, modulus 3 so that it forms a cycle of 3
            if (i < str.length() - 3 && str.charAt(i + 1) == 'a' && str.charAt(i + 2) == 'a' && str.charAt(i + 3) == 'a') {//if an 'a' is followed by more than 2 other 'a' characters in a row
                output += str.substring(i + 1);
                break;
            } else {
                ++aOccurrence; // increment the a's we have encountered so far
            }
        } else {
            output += str.charAt(i); // append the character if it is not a
        }
    }
    return output;
}

【讨论】:

    【解决方案2】:

    我已经编辑了我的答案。这个给出了正确的解决方案:

    public static void main (String[] args) throws InterruptedException, IOException, JSONException {
        System.out.println(aTo123X("ababba")); //xbxxbbxxx
    
        System.out.println(aTo123X("anaceeacdabnanbag")); //xnxxceexxxcdxbnxxnbxxxg
    
        System.out.println(aTo123X("aabaaaavfaajaaj")); //xxxbxxxaaavfaajaaj
    }
    
    public static String aTo123X(String str) {
        String x = "x";
        String xx = "xx";
        String xxx = "xxx";
        int a = 1;
        int brek = 0;
    
        String output = "";
        for (int i = 0; i < str.length(); i++) {
            if(str.charAt(i) == 'a' && a == 1) {
                output += x; 
                str.substring(i+1, str.length());
                a = 2;
                try {
                    if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
                        brek += 1;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else if(str.charAt(i) == 'a' && a == 2) {
                output += xx; 
                str.substring(i+1, str.length());
                a = 3;
                try {
                    if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
                        brek += 1;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else if(str.charAt(i) == 'a' && a == 3) {
                output += xxx; 
                str.substring(i+1, str.length());
                a = 1;
    
                try {
                    if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
                        brek += 1;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else {
                output += str.charAt(i);
                brek = 0;
            }
            if(brek>0) {
                output += str.substring(i+1);
                break;
            }
        }
        return output;
    }
    

    【讨论】:

    • 编辑此答案以匹配 OP 问题要求.. 不是正确的输出和逻辑
    【解决方案3】:

    这是执行相同操作的代码。我已经评论了代码以解释它的作用

    public class ReplaceChar {
    
        public static void main(String... args){
            String[] input =new String[]{"ababba","anaceeacdabnanbag","aabaaaavfaajaaj"};
    
            StringBuilder result = new StringBuilder();
    
            for (int i= 0; i < input.length;i++){
                result.append(getReplacedA(input[i]));
                result.append("\n");
            }
    
            System.out.println(result);
    
        }
    
        private static String getReplacedA(String withA){
            // stringBuilder for result
            StringBuilder replacedString = new StringBuilder();
    
            // counting the number of time char 'a' occurred in String for replacement before row of 'aaa'
            int charACount = 0;
    
            // get the first index at which more than two 'aa' occurred in a row
            int firstIndexOfAAA = withA.indexOf("aaa") + 1;
    
            // if 'aaa' not occurred no need to add the rest substring
            boolean addSubRequired = false;
    
            // if the index is 0 continue till end
            if (firstIndexOfAAA == 0)
                firstIndexOfAAA = withA.length();
            else
                addSubRequired = true;
    
            char[] charString = withA.toCharArray();
    
            //Replace character String[] array
            String[] replace = new String[]{"x","xx","xxx"};
    
            for(int i = 0; i < firstIndexOfAAA; i++){
                    if (charString[i] == 'a'){
                        charACount++;
                    charACount = charACount > 3 ? 1 : charACount ;
                    // add the number x based on charCount
                    replacedString.append(replace[charACount - 1]);
                    }else{
                        replacedString.append(charString[i]);
                    }
            }
    
            // if the String 'aaa' has been found previously add the remaining subString
            // after that index
            if (addSubRequired)
                replacedString.append(withA.substring(firstIndexOfAAA));
    
            // return the result
            return replacedString.toString();
        }
    
    }
    

    输出:

    xbxxbbxxx
    xnxxceexxxcdxbnxxnbxxxg
    xxxbxxxaaavfaajaaj
    

    编辑:一些改进您可以在 getReplacedA() 函数中进行一些极端情况:

    1. 检查 char 'a' 是否存在于字符串中,如果不返回字符串,则无需进一步操作。

    2. 使用 IgnoreCase 来避免大写或小写的可能性。

    【讨论】:

    • 这是一个很好的解决方案,但是,我有更多的输出无法正常工作,我已将它们添加到问题中
    • 因为您的问题陈述现在连续说出超过 2 个其他 'a' 字符。只需将 int firstIndexOfAAA = withA.indexOf("aaa") + 1; 行替换为 int firstIndexOfAAA = withA.indexOf("aaaa") + 1; 即现在我们正在检查超过 2 个字符,即至少 3 个字符。它会正常工作
    【解决方案4】:
    public class NewClass {
    
        public static void main(String[] args) {
            System.out.println(aTo123X("ababba")); // "xbxxbbxxx"
            System.out.println(aTo123X("anaceeacdabnanbag")); // "xnxxceexxxcdxbnxxnbxxxg"
            System.out.println(aTo123X("aabaaaavfaajaaj")); //xxxbxxxaaavfaajaaj
        }
    
        public static String aTo123X(String str) {
            String output = "";
            int aCount = 0;
            int inRow = 0;
            for (int i = 0; i < str.length();) {
                if (str.charAt(i) == 'a') {
                    if (inRow <= 1) {
                        inRow++;
                        aCount++;
    
                        if (aCount == 1) {
                            output += "x";
                        } else if (aCount == 2) {
                            output += "xx";
                        } else {
                            output += "xxx";
                            aCount = 0;
                        }
    
                        boolean multiple = ((i + 1) < str.length()) && (str.charAt(i + 1) == 'a')
                                && ((i + 2) < str.length()) && (str.charAt(i + 2) == 'a');
    
                        if (multiple) {
                            i++;
                            while (i < str.length()) {
                                output += str.charAt(i++);
                            }
                            return output;
                        }
                    } else {
                        output += str.charAt(i);
                    }
                } else {
                    output += str.charAt(i);
                    inRow = 0;
                }
                i++;
            }
            return output;
        }
    }
    

    【讨论】:

      【解决方案5】:

      我使用 Map 来存储替换的位置

          public static void main(String[] args) {
              System.out.println(aTo123X("ababba"));//xbxxbbxxx
              System.out.println(aTo123X("anaceeacdabnanbag"));//xnxxceexxxcdxbnxxnbxxxg
              System.out.println(aTo123X("aabaaaavfaajaaj"));//xxxbxxxaaavfaajaaj
          }
      
          public static String aTo123X(String str){
              String res = "";
              int nthReplace = 1; //Integer to store the nth occurence to replace
              //Map to store [key == position of 'a' to replace]
              //[value == x or xx or xxx]
              Map<Integer, String> toReplacePos = new HashMap<>();
              //The loop to know which 'a' to replace
              for (int i = 0; i < str.length(); i++) {
                  if(str.charAt(i) == 'a'){
                      toReplacePos.put(i, nthReplace % 3 == 1 ? "x": (nthReplace % 3 == 2 ? "xx": "xxx"));
                      nthReplace++;
                      //Break if an 'a' is followed by more than 2 other 'a'
                      try {
                          if((str.charAt(i+1) == 'a') 
                             && (str.charAt(i+2) == 'a') 
                             && (str.charAt(i+3) == 'a')){
                              break;                        
                          }                    
                      } catch (StringIndexOutOfBoundsException e) {
                      }
                  } 
              }
              //Do the replace
              for (int i = 0; i < str.length(); i++) {
                  res += toReplacePos.containsKey(i) ? toReplacePos.get(i) : str.charAt(i);                 
              }
              return res;
          }
      

      【讨论】:

        【解决方案6】:

        我以代码本身的 cmets 形式指出您的代码中的问题。

        public String aTo123X(String str) {
            //You are not using xVal variable in your code, hence it's obsolete
            String xVal = "";
            //You don't need x variable as you can simply use string concatenation
            String x = "x";
            String output = "";
        
            for (int i = 0; i < str.length(); i++) {
        
                /**
                 * Here, in "if" block you have not implmented any logic to replace the 2nd and
                 * 3rd occurence of 'a' with 'xx' and 'xxx' respectively. Also, substring() returns
                 * the sub-string of a string but you are not accepting that string anywhere, and 
                 * you need not even use sub-string as "for" loop will cycle through all the
                 * characters in the string. If use sub-string method you code will only process
                 * alternative characters.
                 */
                 if( str.charAt(i) == 'a') {
                     output += x; 
                     str.substring(i+1, str.length());
                 }
        
                 /**
                  * Because of this statement a's are also returned, because this statement gets 
                  * in both scenarios, whether the current character of string is a or not.
                  * But, this statement should get executed only when current character of the
                  * string is 'a'. So, in terms of coding this statement gets executed no matter
                  * "if" loop is executed or not, but it should get executed only when "if" loop
                  * is not executed. So, place this statement in else block.
                  */
                  output += str.charAt(i);
            }
            return output;
        }
        

        我已经为你实现了逻辑。这是您的问题的解决方案,只需复制并运行它。它通过了所有指定的测试用例。

        public String aTo123X(String str) {
            String output = "";
            int count = 1;
            boolean flag = true;
        
            for (int i = 0; i < str.length(); i++) {
                if(str.charAt(i) == 'a' && flag == true) {
                    switch(count) {
                        case 1: output += "x";
                                count++;
                                break;
        
                        case 2: output += "xx";
                                count++;
                                break;
        
                        case 3: output += "xxx";
                                count = 1;
                                break;
                    }
        
                    if ((str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a') == true) {
                        flag = false;
                    }
                }
                else {
                    output += str.charAt(i);    
                }
            }
        
            return output;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-05
          • 2021-06-26
          • 1970-01-01
          • 2021-12-03
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          • 2015-07-18
          相关资源
          最近更新 更多