Java,格式字符串数组

时间:2015-09-20 11:57:39

标签: java arrays

我有一个java String数组,其中包含如下所示的值:

  arr[0] = "ClassA -> ClassSuper";
  arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
  arr[2] = "ClassC -> Java/lang/object";
  arr[3] = "ClassSuper -> ClassSuperSuper";

如果数组如上所示,我想将这个数组格式化为一个反映上述数组值之间关系的形式。在每个阶级的意义上的关系;该类的超级类应该附加到其中。

作为一个例子,我想格式化上面的数组如下:

  arr[0] = "ClassA -> ClassSuper-> ClassSuperSuper -> ClassSuperSuperSuper";
  arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
  arr[2] = "ClassC -> Java/lang/object";
  arr[3] = "ClassSuper -> ClassSuperSuper -> ClassSuperSuper";

请帮我解决这个问题。我是一个花了几个小时的新手,但仍然无法成功。这就是我到目前为止所做的。

for(int t=0; t<superOrInterfaceList.length;t++) {
   if(superOrInterfaceList[t] != null) {
      String co = superOrInterfaceList[t].substring((superOrInterfaceList[t].lastIndexOf('>')+1),superOrInterfaceList[t].length());

      for(int s=0; s<superOrInterfaceList.length;s++) {
          if(superOrInterfaceList[s] != null) {
              String cof = superOrInterfaceList[s].substring(0,(superOrInterfaceList[s].indexOf('-')));
              if(cof.equals(co)) {
                  superOrInterfaceList[t] = superOrInterfaceList[t]+"->"+cof;

              }
          }
       }

   }
}

但在执行此循环后,我在数组中得到了一些奇怪的值。它只找到1级的超级类,然后反复重复附加它。在运行上面的代码后打印数组时,我得到了类似的答案。

"ClassA-> ClassSuper -> ClassSuper -> ClassSuper ..."

请帮我纠正我的代码。或者,如果你有另一个好方法,请告诉我。 如果您需要更多说明来回答这个问题,请询问。

2 个答案:

答案 0 :(得分:2)

正如斯科特说的那样,更好的数据模型可以为您节省大量的工作:

static class AClass {
    private String name;
    private AClass superClass;

    public AClass(String name) {
        this.name = name;
    }

    public void setSuperClass(AClass superClass) {
        this.superClass = superClass;
    }

    @Override
    public String toString() {
        return name + (superClass != null ? " -> " + superClass : "");
    }
}

// return an object from the map if present; otherwise create, insert and return a new one
private static AClass getOrCreate(String name, Map<String, AClass> map) {
    AClass result = map.get(name);
    if (result == null) {
        result = new AClass(name);
        map.put(name, result);
    }
    return result;
}

public static void main(String[] args) {
    String[] arr = {"A -> B", "C -> D", "D -> E", "B -> C"};
    Map<String, AClass> map = new HashMap<>();

    for (String s : arr) {
        String[] split = s.split("\\s+->\\s+"); // split into [subclass, superclass]
        AClass superClass = getOrCreate(split[1], map);
        getOrCreate(split[0], map).setSuperClass(superClass);
    }
    for (AClass c : map.values()) {
        System.out.println(c);
    }
}

有关split()中使用的正则表达式的详细信息,请参阅Pattern,或者查看所需的任何类和方法的javadoc。

此示例打印所有提到的类,在本例中包括E,即使它们没有超类。它还以未定义的顺序打印它们。如果需要,这些事情应该不难改变。

答案 1 :(得分:1)

请原谅我无视OP的蔑视 我解决了这个问题。我在代码中添加了尽可能多的文档 希望OP学到一些东西......

public static void main(String[] args)
{
    String[] arr = new String[4];
    arr[0] = "ClassA -> ClassSuper";
    arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
    arr[2] = "ClassC -> Java/lang/object";
    arr[3] = "ClassSuper -> ClassSuperSuper";

    int linkLeafIndex, linkRootIndex;
    do {
        // find a "link": leaf (class name at the end) and root (class name at the start) that are equal
        linkLeafIndex = -1;
        linkRootIndex = -1;
        for (int i = 0 ; i < arr.length ; i++) {
            String leaf = getOneClassName(arr[i], Integer.MAX_VALUE);
            for (int j = 0 ; j < arr.length ; j++) {
                if (j != i) {
                    String root = getOneClassName(arr[j], 0);
                    if (leaf.equals(root)) {
                        linkLeafIndex = i;
                        linkRootIndex = j;
                    }
                }
            }
        }

        // if found, merge the two chains 
        if (linkLeafIndex > -1) {
            // since we link two entries, linked array will have length-1;
            String[] tempArr = new String[arr.length-1];
            // put the merged chain first
            tempArr[0] = linkChains(arr[linkLeafIndex], arr[linkRootIndex]);
            // copy all the rest
            int tempArrIndex = 1 ;
            for (int i = 0 ; i < arr.length ; i++) {
                if (i != linkLeafIndex && i != linkRootIndex) tempArr[tempArrIndex++] = arr[i]; 
            }
            // prepare for next iteration
            arr = tempArr;
        }
    // exit the loop when no more links are found
    } while (linkLeafIndex > -1);

    for (int i = 0 ; i < arr.length ; i++) {
        System.out.println(arr[i]); 
    }
}

// extract either a root or leaf class name 
private static String getOneClassName(String chain, int requiredIndex)
{
    String[] classNames = chain.split("->");
    return requiredIndex < classNames.length ? classNames[requiredIndex].trim() : classNames[classNames.length-1].trim() ;
}

// as the name suggests: create a chain out of merging two given Strings 
private static String linkChains(String startChain, String endChain)
{
    String[] startClassNames = startChain.split("->");
    String[] endClassNames = endChain.split("->");
    String[] linkedClassNames = new String[startClassNames.length + endClassNames.length - 1];

    // copy entire starting chain 
    int linkedClassNamesIndex = 0 ;
    for (int i = 0 ; i < startClassNames.length ; i++) {
        linkedClassNames[linkedClassNamesIndex++] = startClassNames[i].trim();
    }
    // copy ending chain without its root 
    for (int i = 1 ; i < endClassNames.length ; i++) {
        linkedClassNames[linkedClassNamesIndex++] = endClassNames[i].trim();
    }
    // create the required String representation  
    String linkedChain = "";
    for (int i = 0 ; i < linkedClassNames.length ; i++) {
        linkedChain += linkedClassNames[i];
        if (i < linkedClassNames.length-1) {
            linkedChain += " -> ";
        }
    }
    return linkedChain;
}