有没有一种方法可以在Java中更改具有相同字符的多个字符串?

时间:2014-07-01 16:11:49

标签: java replace transpose

我正在开发一个应用程序,我必须从一个音阶转换到另一个音阶。

例如:

cdefgab as gabcdef

c为g,d为a,e为b,f为c,g为d,a为e b为f

使用.replace(“c”,“g”)。replace(“d”,“a”)。replace(“e”,“b”)... ###

但是输出是错误的,因为当第一个c被替换为g时,g被替换为d

以下是代码:

    String tune = "cdef gabc";        
    System.out.println(""+tune.replace("c","g")
                                            .replace("d","a")
                                            .replace("g","d"));

电流输出: daef dabd

所需输出: gaef dabg

我希望第一个字符串'c'为'g'而不是'd'

5 个答案:

答案 0 :(得分:4)

试试这个

System.out.println(tune.replace("a", "\uFFFF")
                       .replace("d", "a")
                       .replace("g", "d")
                       .replace("c", "g")
                       .replace("f", "c")
                       .replace("b", "f")
                       .replace("e", "b")
                       .replace("\uFFFF", "e"));

注意:根据定义,\ uFFFF不是有效字符,因此它不会出现在有效字符串中。

答案 1 :(得分:3)

不使用替换:

StringBuilder buf = new StringBuilder();

for ( char c : tune ) {
    buf.append( map(c) );
}

然后根据需要定义地图(字符注释)。

private char map( char originalNote ) {
    switch(originalNote) {
        case 'c': return 'g';
        case 'd': return 'a';
        case 'e': return 'b';            
        case 'f': return 'c';
        case 'g': return 'd';
        case 'a': return 'e';
        case 'b': return 'f';
        default:
          throw new IllegalArgumentException( "Unknown note: " + originalNote );
    }
}

答案 2 :(得分:2)

基本上你的问题是,replace方法不知道并非所有“g”字符都不是原始字符串中的“g”。所以你必须找到一种方法来区分它们。一种方法是首先用“g_”替换“g”,然后在第二次运行中用“d”替换所有“g_”,这样你就可以这样做:

String tune = "cdef gabc";        
String tune_ = tune.replace("c","c_").replace("d","d_").replace("g","g_"));
System.out.println(tune_.replace("c_","g")
                        .replace("d_","a")
                        .replace("g_","d"));

答案 3 :(得分:1)

尝试将其广泛用于任何比例变化:

String newStr = "";
char ch;
int incr = 4;    // Scale notes increment

for(int i = 0; i < tune.length(); i++){
    ch = tune.charAt(i);
    if(ch > 96 && ch < 104){     // a to g
        if(ch > (103 - incr)){
            newStr += (char)(ch + (incr - 7));
        }
        else{             
            newStr += (char)(ch + incr);
        }
    }
    else{
        newStr += (char)ch;
    }
}

答案 4 :(得分:0)

首先看看冲突。它不能使用替换或正则表达式替换,而是做一个我不推荐的解决方法。

c为g,d为a,e为b,f为c,g为d,a为e,b为f

这里:

  • d - &gt; a和a - &gt; e和e - &gt; b和b - &gt; f和f - &gt; c和c - &gt; g和g - &gt; d

然而,问题是仍有冲突取代g - &gt; d和d - &gt;一个。

如果您更改替换的冲突顺序,请执行以下操作:

  • a - &gt; e和e - &gt; b和b - &gt; f和f - &gt; c和c - &gt; g和g - &gt; d和d - &gt;一个

请注意,您仍然无法更换&#39; a&#39;字符。

你看,冲突是循环的。如果你开始更换d - &gt; a,最后a - &gt; e,你从d到a的所有替换以及其他a将从d变为a。如果你反转也会遇到同样的麻烦。

如果没有冲突,我不建议使用replace方法,因为复杂性是O(n ^ k),其中n是要替换的字符串的长度,k是替换的数量你正计划申请。

使用复杂性O(n)执行此操作的最佳方法是使用char读取char并在循环内逐个替换:

        String output = "";
        for(char ch : "cdef gabc".toCharArray()) {
            if(ch == 'g') output += 'd';
            else if(ch == 'c') output += 'g';
            else if(ch == 'f') output += 'c';
            else if(ch == 'b') output += 'f';
            else if(ch == 'e') output += 'b';
            else if(ch == 'a') output += 'e';
            else if(ch == 'd') output += 'a';
            else output += ch; // in case of spaces and other chars that will not be replaced
        }
        System.out.println(output);