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

有没有一种方法可以在Java中更改具有相同字符的多个字符串?,java,replace,transpose,Java,Replace,Transpose,我正在开发一个应用程序,我必须从一个音阶转换到另一个音阶 例如: cdefgab作为gabcdef c为g,d为a,e为b,f为c,g为d,a为e为b为f 使用。替换(“c”、“g”)。替换(“d”、“a”)。替换(“e”、“b”)### 但是输出是一个错误,因为当第一个c被替换为g时,g被d替换 代码如下: String tune = "cdef gabc"; System.out.println(""+tune.replace("c","g")

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

例如: cdefgab作为gabcdef

c为g,d为a,e为b,f为c,g为d,a为e为b为f 使用。替换(“c”、“g”)。替换(“d”、“a”)。替换(“e”、“b”)### 但是输出是一个错误,因为当第一个c被替换为g时,g被d替换 代码如下:

    String tune = "cdef gabc";        
    System.out.println(""+tune.replace("c","g")
                                            .replace("d","a")
                                            .replace("g","d"));
电流输出: 达夫达布

所需输出: gaef dabg

我希望第一个字符串“c”是“g”而不是“d”试试这个

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根据定义不是有效字符,因此它不会出现在有效字符串中。

基本上,您的问题是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"));
不使用替换:

StringBuilder buf = new StringBuilder();

for ( char c : tune ) {
    buf.append( map(c) );
}
然后根据需要定义map(charnote)

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 );
    }
}

尝试此操作,使其对任何比例变化都通用:

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;
    }
}
String newStr=”“;
char ch;
int incr=4;//比例注释增量
对于(int i=0;i96&&ch<104){//a到g
如果(ch>(103-增量)){
newStr+=(char)(ch+(incr-7));
}
否则{
newStr+=(字符)(ch+incr);
}
}
否则{
newStr+=(char)ch;
}
}

首先查看冲突。使用replace或regexreplaceall将不起作用,而是做一个我不推荐的变通方法

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

在这里:

  • d->a和a->e和e->b和b->f和f->c和c->g和g->d
然后,问题是仍然存在替换g->d和d->a的冲突

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

  • a->e和e->b和b->f和f->c和c->g和g->d和d->a
请注意,替换“a”字符时仍会遇到问题

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

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

对于复杂度O(n),最好的方法是逐字符读取,并在循环中逐个替换:

        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);

@Peter谢谢,但是输出是在def ab这样的框中。我希望第一个字母“c”是“g”,第五个字母“g”是“d”。thanks@clem你能说这和我给你的选项有什么不同吗?@PeterLawrey第二个选项只需要3个字母就可以了,但由于我必须将cdefgab转换为gabcdef,因此即使我更改了顺序,问题仍然存在于其他字母表中。@clem您必须对它们进行排序,以便您要转换的字母本身已被转换。如上所述,我是如何确保右边的字母在之前被转换掉的。java的方法是创建一个包含所有音符的
Note
enum,向其添加
transpose(int-halftone)
,然后创建一个
Tune
类,该类包含一组音符,并具有
transpose(Note-from,Note-to)
它使用适当的参数调用每个音符的
转置
方法。除非您获取每个字符(及其位置)并将其转换,否则我看不到任何有效的解决方案…非常感谢!但是你能解释一下这里发生了什么吗?我是一个新的java用户。谢谢