【问题标题】:Can't get replace to work无法更换工作
【发布时间】:2026-01-02 12:50:01
【问题描述】:

我正在制作一个程序,该程序将帮助我使用我们在课程中学到的算法将 DFA 转换为正则表达式。 代码:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.Arrays;
import java.io.*;

public class DFK {
    static ArrayList<Path> done = new ArrayList<Path>();

    public static void print() {
        for(Path i: done) {
            System.out.println("NOT REPLACED: "+ i);
            if(i.isConverted()) {
                System.out.println("WITH REPLACE: "+ i.getConverted()+"\n");
            } else
                System.out.print("\n");
        }
    }

    public static void develop() {
        if(done.get(0).getKP1() > 0) {
            DFK.add(new Path(done.get(0).getP(), done.get(0).getQ(), done.get(0).getK()));
            DFK.add(new Path(done.get(0).getP(), done.get(0).getKP1(), done.get(0).getK()));
            DFK.add(new Path(done.get(0).getKP1(), done.get(0).getKP1(), done.get(0).getK()));
            DFK.add(new Path(done.get(0).getKP1(), done.get(0).getQ(), done.get(0).getK()));
        }
    }

    public static void add(Path x) {
            boolean exists = (done.indexOf(x)==-1 ? false : true);
            if(exists == false) {
                done.add(x);
                if(x.getKP1() >= 2) {
                    DFK.add(new Path(x.getP(), x.getQ(), x.getK()));
                    DFK.add(new Path(x.getP(), x.getKP1(), x.getK()));
                    DFK.add(new Path(x.getKP1(), x.getKP1(), x.getK()));
                    DFK.add(new Path(x.getKP1(), x.getQ(), x.getK()));
                }
            }
    }

    public static void main(String argv[]) throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        int p = 0, q = 0, kp1 = 0;
        Scanner in = new Scanner(System.in);
        System.out.print("p = ");p = in.nextInt();
        System.out.print("q = ");q = in.nextInt();
        System.out.print("k+1 = ");kp1 = in.nextInt();

        System.out.print("\n");
        String rkzero[][] = new String[q][q];
        for(int i=0; i<q ; i++) {
            for(int j=0; j<q ; j++) {
                System.out.print(String.format("r(%d,%d,0): ", i+1, j+1));
                rkzero[i][j]=input.readLine();
            }
        }

        done.add(new Path(p, q, kp1));
        DFK.develop();
        Collections.sort(done);

        for(int z=0; z<q ; z++) {
            for(int j=0; j<q ; j++) {
                for(Path i: done)
                    if(i.getKP1()==1) {
                        String reg = String.format("r(%d,%d,0)",z+1,j+1); //
                        i.setConverted(i.toString().replace( reg , rkzero[z][j])); //HERE IS THE PROBLEM I THINK
                }
            }
        }
        System.out.print("\n");
        DFK.print();
    }
}

class Path implements Comparable<Path> {
    int p,q,kplus1,k;
    String converted = null;

    public int getP() {
        return p;
    }

    public int getQ() {
        return q;
    }

    public int getKP1() {
        return kplus1;
    }

    public int getK() {
        return k;
    }

    public Path(int a, int b, int c) {
        super();
        p = a;
        q = b;
        kplus1 = c;
        k = c-1;
    }

    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!Path.class.isAssignableFrom(obj.getClass())) {
            return false;
        }

        final Path other = (Path) obj;
        if(other.p == this.p && other.q == this.q && other.kplus1 == this.kplus1)
            return true;
        return false;
    }

    public int compareTo(Path other) {
        return other.kplus1-kplus1;
    }

    public String toString() {
        return String.format("r(%d,%d,%d)=r(%d,%d,%d)+r(%d,%d,%d)r(%d,%d,%d)*r(%d,%d,%d)",p,q,kplus1,p,q,k,p,kplus1,k,kplus1,kplus1,k,kplus1,q,k);
    }

    public void setConverted(String x) {
        converted = new String(x);
    }

    public String getConverted() {
        return converted;
    }

    public boolean isConverted() {
        if(converted == null)
            return false;
        return true;
    }
}

当前输出:

p = 1
q = 2
k+1 = 2

r(1,1,0): 0
r(1,2,0): 1
r(2,1,0): 1
r(2,2,0): 0

NOT REPLACED: r(1,2,2)=r(1,2,1)+r(1,2,1)r(2,2,1)*r(2,2,1)

NOT REPLACED: r(1,2,1)=r(1,2,0)+r(1,1,0)r(1,1,0)*r(1,2,0)
WITH REPLACE: r(1,2,1)=r(1,2,0)+r(1,1,0)r(1,1,0)*r(1,2,0)

NOT REPLACED: r(2,2,1)=r(2,2,0)+r(2,1,0)r(1,1,0)*r(1,2,0)
WITH REPLACE: r(2,2,1)=0+r(2,1,0)r(1,1,0)*r(1,2,0)

想要的输出:

p = 1
q = 2
k+1 = 2

r(1,1,0): 0
r(1,2,0): 1
r(2,1,0): 1
r(2,2,0): 0

NOT REPLACED: r(1,2,2)=r(1,2,1)+r(1,2,1)r(2,2,1)*r(2,2,1)

NOT REPLACED: r(1,2,1)=r(1,2,0)+r(1,1,0)r(1,1,0)*r(1,2,0)
WITH REPLACE: r(1,2,1)=1+00*1

NOT REPLACED: r(2,2,1)=r(2,2,0)+r(2,1,0)r(1,1,0)*r(1,2,0)
WITH REPLACE: r(2,2,1)=0+10*1

如您所见,它仅将r(2,2,0) 替换为0,没有别的,我不知道为什么。我在上一个问题中复制了这个问题,但结果发现我的代码中有一个非 ascii 逗号导致了这个问题,但在这里我找不到它。

我用了grep --color='auto' -P -n "[^\x00-\x7F]" DFK.java,没有找到任何非ascii字符,希望不是同一个问题。

程序应该遍历所有具有 kplus1 = 1 的路径,并将所有 r(i,j,0) 替换为我之前输入的字符串。请记住,它还没有完成。

【问题讨论】:

    标签: java string replace


    【解决方案1】:

    错误是我使用 toString 来获取替换内容的字符串,因此我替换了一个字符串,下一次替换我再次使用原始字符串,因此丢弃了最后一个替换,依此类推。

    所以解决方案是在构造函数中将转换后的初始化为与 toString() 相同的字符串:

    converted = String.format("r(%d,%d,%d)=r(%d,%d,%d)+r(%d,%d,%d)r(%d,%d,%d)*r(%d,%d,%d)",p,q,kplus1,p,q,k,p,kplus1,k,kplus1,kplus1,k,kplus1,q,k);
    

    然后主要使用:

    i.setConverted( i.getConverted().replace(reg, rkzero[z][j]) );
    

    所以我将中间解决方案保存在转换中。

    【讨论】: