Как удалить диапазон строковых объектов из массива на основе первых инициалов, введенных пользователем? - PullRequest
1 голос
/ 06 марта 2019

Итак, у меня есть проект, в котором мне нужно создать массив всех пятидесяти штатов. Затем я должен разрешить пользователю вводить две разные буквы алфавита. Затем я должен удалить все состояния, начинающиеся с этих букв, и все состояния между ними. Например. если кто-то ввел «D-I», все состояния, начинающиеся с «D-I», должны быть удалены.

До сих пор я придумал эту программу, однако, когда я ее запускаю, она не только удаляет все состояния в диапазоне введенных мной букв, но также удаляет все состояния перед первой буквой. Например. если я введу «D-I», все состояния, начинающиеся с A-I, будут удалены, когда все состояния должны начинаться с D-I.

Может ли кто-нибудь помочь мне с этим?

import java.util.ArrayList;
import java.util.Scanner;

public class States {
    public static void main(String[] args) {
        String removeStates;
        String firstInitial;
        String secondInitial;
        String stateInitial;
        int first = 0;
        int last = 0;
        
        Scanner input = new Scanner(System.in);
        ArrayList<String> states = new ArrayList<>();
        
        states.add("Alabama");
        states.add("Alaska");
        states.add("Arizona");
        states.add("Arkansas");
        states.add("California");
        states.add("Colorado");
        states.add("Connecticut");
        states.add("Delaware");
        states.add("District of Columbia");
        states.add("Florida");
        states.add("Georgia");
        states.add("Hawaii");
        states.add("Idaho");
        states.add("Illinois");
        states.add("Indiana");
        states.add("Iowa");
        states.add("Kansas");
        states.add("Kentucky");
        states.add("Louisiana");
        states.add("Maine");
        states.add("Maryland");
        states.add("Massachusetts");
        states.add("Michigan");
        states.add("Minnesota");
        states.add("Mississippi");
        states.add("Missouri");
        states.add("Montana");
        states.add("Nebraska");
        states.add("Nevada");
        states.add("New Hampshire");
        states.add("New Jersey");
        states.add("New Mexico");
        states.add("New York");
        states.add("North Carolina");
        states.add("North Dakota");
        states.add("Ohio");
        states.add("Oklahoma");
        states.add("Oregon");
        states.add("Pennsylvania");
        states.add("Rhode Island");
        states.add("South Carolina");
        states.add("South Dakota");
        states.add("Tennessee");
        states.add("Texas");
        states.add("Utah");
        states.add("Vermont");
        states.add("Virginia");
        states.add("Washington");
        states.add("West Virginia");
        states.add("Wisconsin");
        states.add("Wyoming");
        
        System.out.println(states.toString());
        
        System.out.print("Enter the range of the states you would like to remove based on the first initials (e.g. A-D [not case sensitive]): ");
        
        removeStates = input.nextLine();
        
        firstInitial = removeStates.substring(0, 1);
        
        secondInitial = removeStates.substring(2);
        
        for (int i = 0; i < states.size(); i++) {
            stateInitial = states.get(i).substring(0, 1);
            
            if (stateInitial.equalsIgnoreCase(firstInitial) || stateInitial.equalsIgnoreCase(secondInitial)) {
            
                for (int j = i+1; j>0; j--){
                    states.remove(i);
                    i--;
                }
            }
        }
        System.out.println(states.toString());

    }
}

Вот как выглядит мой вывод прямо сейчас. Нижняя / третья строка, где проблема. Как вы можете видеть, когда я ввел «G-K» (кстати, это не чувствительно к регистру), он удалил все состояния, начинающиеся с A-K, а не состояния, начинающиеся с G-K

[Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware, District of Columbia, Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina, South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, Wyoming]
Enter the range of the states you would like to remove based on the first initials (e.g. A-D [not case sensitive]): g-k
[Louisiana, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina, South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, Wyoming]

Ответы [ 4 ]

2 голосов
/ 06 марта 2019

Это можно сделать одним оператором, используя removeIf():

states.removeIf(s -> s.charAt(0) >= 'D' && s.charAt(0) <= 'I');

Вы можете заменить 'D' на removeStates.charAt(0) и 'I' на removeStates.charAt(2).

1 голос
/ 06 марта 2019

Вместо циклов вы можете просто использовать факты, которые

  • Список отсортирован
  • компаратор строки сравнивает лексикографически, поэтому порядок A, Aa, Aaa, Aab, Abb, Baa, ...
  • интерфейс List реализует метод "removeIf", который позволяет вам проверять строку на соответствие правилу, которое вы реализуете

Итак, вместо ваших циклов for вы можете просто написать код:

    firstInitial = removeStates.substring(0, 1);

    secondInitial = removeStates.substring(2);

    states.removeIf(new Predicate<String>() {

        @Override
        public boolean test(String t) {
            boolean isBeforeFirstInitial = (firstInitial.compareTo(t) >=0);
            boolean isAfterLastInitial = (secondInitial.compareTo(t) <=0);
            boolean startsWithLastInitial = t.startsWith(secondInitial);

            return !(isBeforeFirstInitial||isAfterLastInitial)||startsWithLastInitial;
        }
    });

не забудьте преобразовать инициалы в верхний регистр (ваш текст утверждает, что ввод НЕ чувствителен к регистру)

1 голос
/ 06 марта 2019

Вот альтернативный метод удаления нежелательных состояний с использованием потоков:

char firstInitial = removeStates.charAt(0);
char secondInitial = removeStates.charAt(2);

Collection<String> statesToRemove = states.stream()
       .filter(state -> state.charAt(0) >= firstInitial)
       .filter(state -> state.charAt(0) <= secondInitial)
       .collect(Collectors.toList());

states.removeAll(statesToRemove);

Вы также можете просто настроить фильтр, чтобы отфильтровать только оставшиеся состояния, чтобы сделать его еще проще.

0 голосов
/ 06 марта 2019

Не пытаться звучать значит здесь, но это действительно так, что вы написали:

for (int j = i+1; j>0; j--){
                states.remove(i);
                i--;
            }

Допустим, у вас первая буква была буквой 'C', первый индекс, в который вы вошли бы во внешний циклво внутренний цикл будет я == 4 (Калифорния).Затем вы вызываете внутренний цикл с начальным значением для j = i + 1 = 5 и постепенно перемещаетесь вниз по индексам массива.Таким образом, вы удаляете 5 (от одного до высокого значения), затем 4, затем 3, затем 2 и так далее.Поэтому, как только вы нашли первый, вы удаляете все записи, ведущие к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...