2014-10-30 36 views
1

我正在写一个方法,该方法应该采用格式为"s1:{1,2,3,4}"的输入String并将其放入Set。集合类我已经开发了自己,如下:如何解析一个字符串的集合?

public class Set<E> implements Iterable<E> { 
    private static final int DEFAULT_CAPACITY = 20; 
    private String name; 
    private E[] theData; 
    private int size = 0; 
    private int capacity = 0; 

    public Set(){ 
     capacity = DEFAULT_CAPACITY; 
     theData = (E[]) new Object[capacity]; 
    }//end constructor 

    public Set(String name){ 
     capacity = DEFAULT_CAPACITY; 
     theData = (E[]) new Object[capacity]; 
     this.name = name; 
    }//end constructor 

    public String getName(){ 
     return name; 
    }//end getName 

    public void setName(String name){ 
     this.name = name; 
    }//end setName 

    //adds object to set 
    public void add(Object E) { 
     if (size == capacity) { 
      reallocate(); 
     }//end if 

     theData[size] = (E) E; 
     size++; 

     for (int j = 0; j<size; j++) { 
      for (int k = 0; k < size; k++) { 
       if ((int)theData[j] < (int)theData[k]) { 
        E temp = theData[j]; 
        theData[j] = theData[k]; 
        theData[k] = temp; 
       }//end if 
      }//end nested for loop 
     }//end for loop 

     int counter = 0; 
     for (int i = 0; i < size; i++) { 
      if (E == theData[i]) { 
       counter++; 

       if (counter >= 2) { 
        remove((Object)E); 
       }//end nested if 
      }//end if 
     }//end for loop 
    }//end add method 

    public E get(int i) { 
     if (i < 0 || i >= size) { 
      throw new ArrayIndexOutOfBoundsException(i); 
     } else { 
      return theData[i]; 
     }//end else 
    }//end get method 

    public E remove(int i) { 
     if (i < 0 || i >= size) { 
      throw new ArrayIndexOutOfBoundsException(i); 
     }//end if 

     E returnValue = theData[i]; 
     for (int j = i + 1; j < size; j++) { 
      theData[j - 1] = theData[j]; 
     }//end for loop 

     size--; 
     return returnValue; 
    }//end remove method 

    public void remove(Object E) { 
     for (int i = 0; i < size; i++) { 
      if (E == theData[i]) { 
       for (int j = i + 1; j < size; j++){ 
        theData[j - 1] = theData[j]; 
       }//end nested for loop 

       size--; 
      }//end if 
     }//end for loop 
    }//end remove method 

    //fix! 
    public int find(Object E) { 
     int first, last, middle; 
     first = 0; 
     last = size - 1; 
     middle = (first+last)/2; 

     while(first <= last) { 
      if ((int)theData[middle] > (int)E) { 
       last = middle - 1;  
      } else if ((int)theData[middle] < (int)E) { 
       first = middle + 1; 
      } else { 
       return middle; 
      }//end else 
     }//end while 

     if (first > last) { 
      return -1; 
     }//end if 

     return -1; 
    }//end find method 

    public Set<E> union(Set<E> s) { 
     Set<E> returnSet = new Set<E>(); 

     for (int i = 0; i < this.size; i++) { 
      returnSet.add(this.theData[i]); 
     }//end for loop 

     for (int i = 0; i < s.size; i++) { 
      returnSet.add(s.theData[i]); 
     }//end for loop 

     return returnSet; 
    }//end union method 

    public Set<E> intersect(Set<E> s) { 
     Set<E> returnSet = new Set<E>(); 

     for (int i = 0; i < this.size; i++) { 
      for (int j = 0; j < s.size; j++) { 
       if (this.theData[i] == s.theData[j]){ 
        returnSet.add(theData[i]); 
       }//end if 
      }//end nested for loop 
     }//end for loop 

     return returnSet; 
    }//end intersect method 

    public Set<E> subtract(Set<E> s) { 
     Set<E> returnSet = new Set<E>(); 

     for (int i = 0; i < this.size; i++) { 
      for (int j = 0; j < s.size; j++) { 
       if (this.theData[i] == s.theData[j]) { 
        this.remove((Object)this.theData[i]); 
        s.remove((Object)s.theData[j]); 
       }//end if 
      }//end nested for loop 
     }//end for loop 

     for (int i = 0; i < this.size; i++) { 
      returnSet.add(this.theData[i]); 
     }//end for loop 

     for (int i = 0; i < s.size; i++) { 
      returnSet.add(s.theData[i]); 
     }//end for loop 

     return returnSet; 
    }//end subtract method 

    public boolean equals(Set<E> s) { 
     boolean result = false; 

     for (int i = 0; i < this.size; i++) { 
      if (this.theData[i] == s.theData[i]) { 
       result = true; 
      }//end if 

      if (this.theData[i] != s.theData[i]) { 
       result = false; 
       break; 
      }//end if 
     }//end for loop 

     return result; 
    }//end equals method 


    private void reallocate() { 
     capacity = 2*capacity; 
     theData = Arrays.copyOf(theData, capacity); 
    }//end reallocate method 

    public String toString() { 
     StringBuilder set = new StringBuilder(); 
     set.append("{"); 

     for (int i = 0; i < size; i++) { 
      set.append(theData[i]); 

      if (i != size-1){ 
       set.append(","); 
      }//end if 
     }//end for loop 

     set.append("}"); 

     return set.toString(); 
    }//end toString() 

    public SetIterator<E> iterator() { 
     SetIterator<E> it = new SetIterator<E>() { 
      private int currentIndex = 0; 

      public boolean hasNext() { 
       if (currentIndex < size && theData[currentIndex] != null){ 
        currentIndex++; 
        return true; 
       } else{ 
        return false; 
       }//end else 
      }//end hasNext() 


      public E next() { 
       if (!hasNext()) { 
        throw new NoSuchElementException(); 
       }//end if 

       return theData[currentIndex++]; 
      }//end next() 


      public boolean hasPrevious() { 
       if (currentIndex <= size && currentIndex > 0) { 
        currentIndex--; 
        return true; 
       } else { 
        return false; 
       }//end else 
      }//end hasPrevious() 


      public E previous() { 
       if (!hasPrevious()) { 
        throw new NoSuchElementException(); 
       }//end if 

       return theData[currentIndex--]; 
      }//end previous() 


      public void add(E item) { 
       theData[currentIndex-1] = item; 
      }//end add() 


      public void remove() { 
       for (int i = 0; i < size; i++) { 
        if (theData[currentIndex] == theData[i]) { 
         for (int j = i + 1; j < size; j++) { 
          theData[j - 1] = theData[j]; 
         }//end nested for loop 

         size--; 
        }//end if 
       }//end for loop 
      }//end remove() 
     };//end new SetIterator() 

     return it; 
    }//end iterator method 
}//end Set class 

的方法是应该

  • 抛出一个异常,如果该方法具有无效的格式,如"s1:[1 2,3,4}"这个例子是缺少逗号和大括号)。
  • 此外,输入可能具有任意数量的空白,并且仍将被视为有效。例如:"s1: {1, 2, 3, 4 }"

到目前为止,所有我的方法是:

public Set<Integer> parse(String input){ 
    String s[] = input.split(":"); 
    String name = s[0]; 
    Set<Integer> returnSet = new Set<Integer>(name); 

    return returnSet; 
} 

我不确定如何正确地检索出字符串在集合中的元素,并把它们放到一个Set对象。我知道我可以parseInt一旦我自己得到它们,但我无法隔离每个元素。对于一套可以有多少个元素没有限制;这意味着我的代码应该可以处理任意数量的元素。

我也考虑过正则表达式,但我觉得好像有一个更有效的方法来做到这一点。

任何帮助将不胜感激!

+0

请注意,String.split需要一个正则表达式作为参数。你为什么不简单地在String []数字= s [1] .substring(1,s [1] .length).split(“,”)上使用另一个分割,然后迭代数字 - > trim - > parseInt - >添加到你的设置。如果parseInt失败 - >语法错误。 – nomoa 2014-10-30 18:26:09

回答

0

这是一个工作示例: 首先,您将创建一个正则表达式模式以匹配{}的内部,然后您将检查天气的内部是否正确格式化。 然后你会把{}的内部转换成一个ArrayList。

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
import java.util.*; 

public class Test { 

    public String test = "s 1 : {1, 2,3 ,4}"; 

    public Test() { 
     //match the inside of {} 
     Pattern pattern = Pattern.compile("^s\\s*\\d+\\s*:\\s*\\{([0-9,\\s*]*)}"); 

     Matcher matcher = pattern.matcher(test); 


     // check all occurance 
     while (matcher.find()) { 
      if(matcher.group(1).trim().matches("^(\\d*)+(\\s*,\\s*\\d*)*$")) { 
       System.out.println("valid string"); 
       List<String> items = Arrays.asList(matcher.group(1).split("\\s*,\\s*")); 
       for(String number: items) { 
        System.out.println(number.trim()); 
       } 
      }else{ 
       System.out.println("invalid string"); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new Test(); 
    } 
} 
+0

一个无效的输入s1:{1 2,3,4}将会因为您的替换而生效所有 – nomoa 2014-10-30 18:31:57

+0

您是对的我会纠正它 – Lubo 2014-10-30 18:36:14

+0

现在它应该工作 – Lubo 2014-10-30 19:08:37

0

我已经给你所需的最小代码。这将匹配或返回null。然后你得到标签和字符串集。如果你真的需要Integer对象,你可以像下面的f2()一样简单地转换。你需要添加的是错误处理和更多评论。查看JavaDoc API以获取有关Pattern/Matcher的更多信息。另外,不要简单地使用HashSet。如果订单对您很重要,您至少需要一个LinkedHashSet。如果允许重复,请勿使用哈希任何东西!使用LinkedList或数组。

顺便说一下,你的分割字符串的方法没有错,但它会更复杂。你必须按以下方法拆分:,然后调用str.trim()来删除任何多余的空格str.substring(startIndx,endIndex),最后你可以解析数字列表。您将不得不使用str.indexOf(“{”)或手动搜索来获取索引。

import java.util.Arrays; 
import java.util.LinkedHashSet; 
import java.util.Set; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 


public class NewClass { 

    //match this 
    //STR:{NUM_LIST} 
    //[A-Za-z0-9_]+ = STR is upper and lower alpha, number or underscore; 1 or more characters (in any order) 
    //[0-9,]+ = NUM_LIST is one or more characters and can only contain numbers or comma (in any order) 
    //The() used will give us a group 
    //I like to explicitly use [] to specify a character, but it may not be needed 
    //use a slash (needs a 2nd because of Java) to make sure it is interpreted as just a character and not as a structure of syntax. 
    Pattern p=Pattern.compile("([A-Za-z0-9_]+)[:][\\{]([0-9,]+)[\\}]"); 

    Set test(String txt){ 
     Matcher m=p.matcher(txt); 
     if(!m.matches())return null; 
     int groups=m.groupCount();//should only equal 3 (default whole match+2groups) here, but you can test this 

     System.out.println("Matched: " + m.group(0)); 
     String label = m.group(1); 
     String[] arr = m.group(2).split(","); 

     Set<String> set = new LinkedHashSet(Arrays.asList(arr)); 

     return set; 
    } 

    Object[] test2(String txt){ 
     Matcher m=p.matcher(txt); 
     if(!m.matches())return null; 
     int groups=m.groupCount();//should only equal 3 (default whole match+2groups) here, but you can test this 

     System.out.println("Matched: " + m.group(0)); 
     String label = m.group(1); 
     String[] arr = m.group(2).split(","); 

     Set<String> set = new LinkedHashSet(Arrays.asList(arr)); 
     Object[] ret=new Object[3]; 
     ret[0] = m.group(0); 
     ret[1] = label; 
     ret[2] = set; 
     return ret; 
    } 
} 


void f2(String[] arr){ 
    ArrayList<Integer> list=new ArrayList<Integer>(1000); 
    for(String s: arr){ 
     try { 
      list.add(Integer.parseInt(s)); 
     } catch (NumberFormatException numberFormatException) { 
      System.out.println(numberFormatException+ "\t-->\t"+ s); 
     } 
    } 
    Set<Integer> set = new LinkedHashSet(list); 
} 
+0

确保您只调用一次Pattern.compile,因为它非常耗时。如果你有一个循环,如果你有1M字符串需要解析,它可能会永远持续下去。 – ldmtwo 2014-10-30 19:00:15