Манипуляция строк без какого-либо списка массивов или дерева? - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть входные данные в виде строки.Мне нужно сделать несколько следующих вещей:

  1. Слова должны быть напечатаны в порядке увеличения длины;
  2. Слова, повторенные более одного раза, игнорируются.
  3. После того жеразмер слова размер слова для печати.

Например: Input : the Black lion was bigger than the red lion;

Output : the was 3 than black 4 ... so on....till the end!

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

import java.util.*;
class Sorted implements Comparator<String> {

    public int compare(String o1, String o2) {
        if (o1.length() < o2.length()) {
            return -1;
        } else if (o1.length() > o2.length()) {
            return 1;
        } else {
            return 0;
        }
    }
}public class smallToLarge {
    public static void main(String[] args) {
        List<String> arrList = new ArrayList<String>();
        Scanner o = new Scanner(System.in);
        System.out.println("Enter the Sentence : ");
        String sentance = o.nextLine().toLowerCase();
        String[] str = sentance.split("\\s+");
        Arrays.sort(str, new Sorted());
        for (int i = 0; i < str.length; i++) {
            if (!arrList.contains(str[i])) {
                arrList.add(str[i]);
            }
        }
        for (int j = 0; j < arrList.size(); j++) {
            System.out.print(arrList.get(j) + " " + arrList.get(j).length() + " ");
        }
    }
}

Ответы [ 5 ]

2 голосов
/ 23 сентября 2019

Будучи немым, нужно больше ходить.Здесь я использую одну структуру данных: StringBuilder для сбора слов одинаковой длины, поскольку можно легко проверить наличие дублирующих слов.

int lastSize = 0;
for (;;) {
    int nextSize = determineNextSize(lastSize, input);
    if (nextSize <= lastSize) {
        break;
    }
    StringBuilder words = new StringBuilder();
    collectUniqueWordsOfLength(input, nextSize, words);
    lastSize = nextSize;
    System.out.print(words + lastSize + " ");
}
System.out.println();

Методы обхода входной строки:

int determineNextSize(String input, int size) {
    int minSize = -1;
    int p0 = 0;
    while (p0 < innput.length()) {
        int p = input.indexOf(' ', p0);
        if (p == -1) {
            p = input.length();
        }
        int wordSize = p - p0;
        if (wordSize  > size && (minSize == -1 || wordSize  < minSize)) {
            minSize = wordSize ;
        }
        p0 = p + 1;
    }
    return minSize;
}

void collectUniqueWordsOfLength(String input, int size, StringBuilder words) {
    int p0 = 0;
    while (p0 < innput.length()) {
        int p = input.indexOf(' ', p0);
        if (p == -1) {
            p = input.length();
        }
        int wordSize = p - p0;
        if (wordSize  == size)) {
            String word = input.substring(p0, p) + " ";
            if (!words.toString().contains(word)) {
                words.append(word);
            }
        }
        p0 = p + 1;
    }
}
2 голосов
/ 23 сентября 2019

Если вы можете использовать потоки, вы можете сделать это просто так:

String input = "the Black lion was bigger than the red lion";
Pattern.compile("\\s+")
       .splitAsStream(input)
       .collect(Collectors.groupingBy(String::length,TreeMap::new,Collectors.toSet()))
       .forEach((k,v)->{ System.out.print(v + " " + k + " ");});

//to get the output
//[the, red, was] 3 [than, lion] 4 [Black] 5 [bigger] 6

Объяснение:

  • Разделить ввод в каждом пробеле
  • Соберите их, группируя по длине
  • в TreeMap, чтобы отсортировать их по возрастанию
  • toSet для удаления дубликатов

Если вы не хотите, чтобы строки в скобках менялисьпоследняя строка до:

.forEach((k,v)->{ System.out.print(String.join(" ", v) + " " + k + " ");});
0 голосов
/ 23 сентября 2019

Я постараюсь ответить на основании того, как я понимаю ваши требования, которые я перечислю сначала:

  1. Слова должны быть отсортированы по длине и, возможно, также по лексическому принципу (так что «красный» перед«the» и т. д.)
  2. Слова, которые появляются более двух раз («повторяется более одного раза»), следует игнорировать
  3. Слова должны быть напечатаны и всякий раз, когда длина изменяет длину предыдущегогруппа должна быть напечатана

Для этого вы можете сделать следующее:

  1. разбить текст на отдельные слова, создавая массив или список (вы можете разбить на пробели пунктуация)
  2. итерация один раз, чтобы "преобразовать" каждое слово в строчную форму (это может быть вставлено при необходимости)
  3. сортировка массива / списка слов с помощью компаратора, который сравнивает длинусначала и, если длина равна, сравнивает строки лексически
  4. итерирует слова снова и собирает их в LinkedHashMap, где слово является ключом, а значение равносчетчик для этого слова
  5. итерирует по набору записей этой карты, пропускает любое слово, счетчик которого больше 2 (или 1, в зависимости от того, как требование нет.2 следует интерпретировать)
  6. отслеживать длину предыдущего слова и всякий раз, когда она отличается от длины текущего слова, печатать либо длину (в зависимости от того, нужно ли печатать длину до или после словсами)
0 голосов
/ 23 сентября 2019
String str =  "the Black lion was bigger than the red lion";

str = Arrays.stream( str.split("\\s+")).distinct().collect(Collectors.joining(" ") );

    for (int i = 0 ; i <= str.length() ; i++) {
        Matcher m = Pattern.compile("\\b\\w{"+i+"}\\b").matcher(str);
        while(m.find()){
            System.out.print(m.group(0) +" ");
        }
    }

При использовании регулярного выражения вам нужно будет изменить некоторые изменения, например напечатать длину слова.надеюсь, это поможет вам.

0 голосов
/ 23 сентября 2019

Вот простое доказательство концепции с использованием потоков / коллекторов:

public static void main(String[] args)
{
  List<String> arrList = new ArrayList<String>();
  String sentence = "the Black lion was bigger than the red lion";
  var words = sentence.split("\\s");
  // take all the words
  var sortedByLength = Arrays.stream(words)
    // group by string length
    .collect(Collectors.groupingBy(String::length, 
      // sort by string length
      TreeMap::new, 
      // unique words
      Collectors.toSet()));
  // for every length-List(word) pair
  for(var entry : sortedByLength.entrySet())
  {
    // for every word in List(word)
    for(var word : entry.getValue())
    {
      System.out.print(word+" ");
    }
    System.out.print(entry.getKey()+" ");
  }
}

Вывод:

the red was 3 than lion 4 Black 5 bigger 6

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

Вот аналогичное подтверждение концепции, не использующее списки, Tree (set / map) s или Regex:

public static void main(String[] args)
{
  String sentence = "the Black lion was bigger than the red lion";
  var words = sentence.split("\\s");
  if(words.length == 0)
    return;
  int nulls = 0;
  for(int i = 0; i < words.length; i++)
  {
    for(int j = i+1; j < words.length; j++)
    {
      if(words[i].equals(words[j]))
      {
        words[i] = null;
        nulls++;
        break;
      }
    }
  }
  var noDupes = new String[words.length - nulls];
  int index = 0;
  for(int i = 0; i < words.length; i++)
  {
    if(words[i] != null)
      noDupes[index++] = words[i];
  }
  Arrays.sort(noDupes, Comparator.comparingInt(String::length));
  for(int i = 0; i < noDupes.length; i++)
  {
    System.out.print(noDupes[i]+" ");
    if(i == noDupes.length - 1)
    {
      System.out.println(noDupes[i].length());
    }
    else if(noDupes[i+1].length() > noDupes[i].length())
    {
      System.out.print(noDupes[i].length()+" ");
    }
  }
}

Вывод:

was the red 3 than lion 4 Black 5 bigger 6

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

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