如何在不重复的情况下将字符串数组扫描并操作到不同的多维数组中?

时间:2011-04-14 00:30:48

标签: java arrays arraylist

对不起,标题有点令人困惑。我需要做的是阅读一个包含一堆城市和州的文本文件,分别在这样的行上:

Salem, Oregon
St. George, Utah
Augusta, Maine
Portland, Maine
Jefferson City, Missouri
Kansas City, Missouri
Portland, Oregon
Salt Lake City, Utah

然后从中得到一个输出:

Maine: Augusta, Portland
Missouri: Jefferson City, Kansas City
Oregon: Portland, Salem
Utah: Salt Lake City, St. George

我必须在一个方法中完成它并发送到一个多维数组或arraylist,其中第一个维度是状态,第二个维度是相应的城市。

我认为最简单的方法就是为每个城市和州制作排序令牌,但我不知道如何在事后对其进行适当的排序。我已经创造了令牌,然后只是将它们重新打印到单独的线上,这简直无用。

这是我目前的代码:

import java.io.File;
import java.util.Scanner;
import java.util.Formatter;
import java.io.FileNotFoundException;
import java.util.Arrays;

public class Munge
{

    private String inFileName, outFileName;
    private Scanner inFile;
    private Formatter outFile;
    private int line = 0;

    private String[] data;

    public Munge(String inFileName, String outFileName)
    {
        this.inFileName = inFileName;
        this.outFileName = outFileName;

        data = new String[100];
    }

    public void openFiles()
    {
        try
        {
            inFile = new Scanner(new File(inFileName));
        }
        catch(FileNotFoundException exception)
        {
            System.err.println("File not found.");
            System.exit(1);
        }
        catch(SecurityException exception)
        {
            System.err.println("You do not have access to this file.");
            System.exit(1);
        }

        try
        {
            outFile = new Formatter(outFileName);
        }
        catch(FileNotFoundException exception)
        {
            System.err.println("File not found.");
            System.exit(1);
        }
        catch(SecurityException exception)
        {
            System.err.println("You do not have access to this file.");
            System.exit(1);
        }
    }

    public void readRecords()
    {
        while(inFile.hasNext())
        {
            data[line] = inFile.nextLine();
            System.out.println(data[line]);
            line++;
        }
    }

    public void writeRecords()
    {
        for(int i = 0; i < line; i++)
        {
            String tokens[] = data[i].split(", ");
            Arrays.sort(tokens);

            for(int j = 0; j < tokens.length; j++)
                outFile.format("%s\r\n", tokens[j]);
        }
    }

    public void closeFiles()
    {
        if(inFile != null)
            inFile.close();

        if(outFile != null)
            outFile.close();
    }
}

我真的不知道我在做什么,而且我对Java和任何编程的理解都非常有限。我现在已经花了太多时间。如果有人能帮助我,我会非常感激。

5 个答案:

答案 0 :(得分:1)

您需要拥有每个州的城市列表。

所以,你会得到类似Map<String, List<String>>的东西,在解析(即拆分)你的输入后,你会查找你所在州的正确名单并放入城市。

最后,您遍历地图以正确的顺序打印出所有内容。

答案 1 :(得分:1)

我建议使用HashMap将每个州名称映射到城市名称的ArrayList。在处理每个输入记录时,从HashMap检索状态的ArrayList。如果不存在,则这是状态的第一条记录,因此创建一个新的ArrayList并将其放在状态名称下的HashMap中。假设任何特定的城市/州对只出现一次,您不需要检查重复项。如果最后需要它作为多维数组,则可以在处理完所有内容后从HashMap中提取所有键/值对。

答案 2 :(得分:1)

尝试使用状态名称作为键,使用Hashtable来解决此问题。

默认情况下,在“哈希冲突”(状态 - 城市对已经存在)的情况下,密钥的单个存储桶存储多个条目,可以使用HashTable Java API顺序搜索。最后,您最终会得到一个数据结构,您可以在该数据结构中以状态为键访问城市。

或者,您可以使用状态名称作为键并将数组列表存储为值。如果给定状态,则没有与之关联的值,创建新的ArrayList,将城市添加到其中,然后将ArrayList作为一对存储在HashTable中。如果给定状态,则ArrayList已作为值存在,检索ArrayList并插入您的城市。 :)

您可以在Java 6 api中查找数据结构。

HashTable

答案 3 :(得分:0)

以下是一些带有评论的代码,希望有所帮助:

// your input file with city, state values
File file = new File("states.txt");

// data structure to hold mapping of state to list of cities, sorted by state
SortedMap<String, List<String>> map = new TreeMap<String, List<String>>();

// scan file by line and populate data structure
Scanner scanner = new Scanner(file).useDelimiter("\\n");
while (scanner.hasNext()) {
    String line = scanner.next();

    // only process lines with a comma
    if (line.contains(",")) {
        // split the line on the comma and extract the city and state
        // note this won't work properly if the city has a comma in it
        String[] parts = line.split(",");
        String city = parts[0].trim();
        String state = parts[1].trim();

        // if the state doesn't exist in the map yet, create it
        List<String> cities = map.get(state);
        if (cities == null) {
            cities = new ArrayList<String>();
            map.put(state, cities);
        }

        // add the city to the list for the state if it's not in it yet
        if (!cities.contains(city)) {
            cities.add(city);
        }
    }
}

// iterate over the states for output
for (String state : map.keySet()) {
    // build up a string for each state with the list of cities
    StringBuilder sb = new StringBuilder();

    // start with the state
    sb.append(state + ": ");

    // now append the cities
    List<String> cities = map.get(state);
    for (String city : cities) {
        sb.append(city + ", ");
    }

    // remove the last comma
    sb.delete(sb.length() - 2, sb.length());

    // print out the finished line
    String output = sb.toString();
    System.out.println(output);
}

答案 4 :(得分:0)

使用HashMap或ArrayList的代码。 HashMap的关键代表状态,ArrayList将包含城市 免责声明:我在记事本中键入了代码,因此可能存在编译错误。但是你明白了。

/*
Store each State as a key in the HashMap.
For each State assign an arraylist of cities.
We use StringTokenizer to split the state and the city.
*/
HashMap<String,ArrayList<String>> hmStateCity = new  HashMap<String,ArrayList<String>>();

public void readRecords()
{
      while(inFile.hasNext())
     {
       String sInputLine = inFile.nextLine();
       StringTokenizer stInput = new StringTokenizer(sInputLine , "," , true);
       int i = 0; //when i is 0 = State, 1 = city
    ArrayList<String> arrCity = new ArrayList<String>();
       while (stInput.hasMoreElements()) 
       {
          String sToken = stInput.nextElement();
          if( i == 0)
          {
               arrCity = hmStateCity.get( sToken );
               if(arrCity  == null)
               {    // this indicates that this particular State was never created.
                    // so assign a new ArrayList to the State. 
            arrCity = new ArrayList<String>();
            hmStateCity.put( token , arrCity );
               }
          }
          else if( i == 1 )
          {
               arrCity.add( sToken );
          }

          i++;
       }
     }
}

/* Iterate through HashMAp. The Map's key is the State name.
Retrieve the List of cities using the "State".
The String sStateCityLine  will have each line that can be written one at a time.
*/

public void writeRecords()
{
    if(hmStateCity !=null)
    {
        Set<String> setStateName = hmStateCity.keySet();

        for(String sState : setStateName )
        {
            String sStateCityLine = sState + ":" ;
            ArrayList<String> arrCity = hmStateCity.get( sState );
            if( arrCity!=null && !arrCity.isEmpty() )
            {
                boolean isFirstCity = true;
                for(String sCity : arrCity )
                {
                    if( !isFirstCity )
                    {
                        sStateCityLine  = sStateCityLine  + ",";
                    }
                    sStateCityLine  = sStateCityLine  + " " + sCity;
                    isFirstCity = false;
                }
            }

            //Insert code here to write the String sStateCityLine line by line
        }
    }
}