Как я могу сканировать и манипулировать массивом строк в другом многомерном массиве без дубликатов? - PullRequest
3 голосов
/ 14 апреля 2011

Извините за название немного запутанным. Что мне нужно сделать, это прочитать текстовый файл с кучей городов и штатов в отдельных строках, как это:

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

Мне нужно сделать это одним методом и отправить в многомерный массив или массив, где первое измерение будет состояниями, а второе измерение - соответствующими городами.

Я предположил, что самый простой способ сделать это - создать токены для каждого города и штата, но я не знаю, как правильно их отсортировать после этого. Я дошел до того, что создал токены, а затем просто перепечатал их на отдельные строки, что является ничем иным, как бесполезным.

Вот мой текущий код:

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 ]

1 голос
/ 14 апреля 2011

Я бы предложил использовать HashMap, который отображает каждое название штата в ArrayList названий городов.По мере обработки каждой входной записи извлекайте ArrayList для состояния из HashMap.Если его там нет, то это первая запись для состояния, поэтому создайте новый ArrayList и поместите его в HashMap под именем состояния.Предполагая, что любая конкретная пара город / штат встречается только один раз, вам не нужно проверять дубликаты.Если в конце вам понадобится многомерный массив, вы можете извлечь все пары ключ / значение из HashMap после того, как все будет обработано.

1 голос
/ 14 апреля 2011

Попробуйте решить эту проблему, используя Hashtable, используя имена состояний в качестве ключей.

По умолчанию, в случае «коллизии хэшей» (пара «штат-город» уже существует), в одной корзине для ключа хранится несколько записей, которые можно искать последовательно, используя Java-API HashTable. В итоге вы получаете структуру данных, в которой вы можете получить доступ к городам, указав в качестве ключа состояние.

Кроме того, вы можете использовать имена состояний в качестве ключей и сохранять списки массивов в качестве значений. Если задано состояние, с ним не связано никакого значения, создайте новый ArrayList, добавьте в него свой город, затем сохраните ArrayList в виде пары в HashTable. Если задано состояние, ArrayList уже существует в качестве значения, извлеките ArrayList и вставьте свой город. :)

Вы можете посмотреть структуру данных в API Java 6.

HashTable

1 голос
/ 14 апреля 2011

У вас должен быть список городов для каждого штата.

Итак, у вас будет что-то вроде Map<String, List<String>>, и после синтаксического анализа (т.е. разделения) вашего ввода вы найдете правильный список для своего штата и поместите в город.

В конце вы перебираете карту, чтобы распечатать все в правильном порядке.

0 голосов
/ 14 апреля 2011

Код с использованием 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
        }
    }
}
0 голосов
/ 14 апреля 2011

Вот код с комментариями для вас, надеюсь, это поможет:

// 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...