重新排列单词以在一行中容纳最多单词并使用 Java 创建更少的行数
Posted
技术标签:
【中文标题】重新排列单词以在一行中容纳最多单词并使用 Java 创建更少的行数【英文标题】:Re-shuffle the words to accommodate max words in a single line and create less number of lines using Java 【发布时间】:2019-10-08 18:16:19 【问题描述】:重新排列单词以在 42 个字符的单行中容纳最多单词,并使用 Java 创建更少的行数
我必须创建逗号分隔的单词,并且一行的最大大小为 42。 字符串可以以这样的方式重新洗牌,以适应最大字数而不会超过 42 行大小和更少的行数。 为此,我根据单词的长度对单词进行了排序。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ManageWords
private static final int LINE_MAX_SIZE = 45;
public static void main(String[] args)
List<String> wordList = new ArrayList<String>();
wordList.add("URUNDI");
wordList.add("AFGHANISTAN");
wordList.add("WEST GERMANY");
wordList.add("ALAND ISLANDS");
wordList.add("VIET-NAM - DEMOCRATIC REPUBLIC OF");
Collections.sort(wordList, Comparator.comparingInt(String::length));
List<String> concatenatedWordsLines = new ArrayList<String>();
for (int i = 0; i < wordList.size(); i++)
String concatenatedWords = wordList.get(i);
int j = i + 1;
if (concatenatedWords.length() < LINE_MAX_SIZE)
while (concatenatedWords.length() < LINE_MAX_SIZE && j <= wordList.size() - 1)
if (concatenatedWords.concat("," + wordList.get(j)).length() < LINE_MAX_SIZE)
concatenatedWords = concatenatedWords.concat("," + wordList.get(j));
else
break;
j++;
concatenatedWordsLines.add(concatenatedWords);
i = j - 1;
for (String s : concatenatedWordsLines)
System.out.println(s + " : " + s.length());
使用上面的代码,我得到以下 3 行的结果,
URUNDI,AFGHANISTAN,WEST GERMANY
ALAND ISLANDS
VIET-NAM - DEMOCRATIC REPUBLIC OF
而我期望它在 2 行中,其大小小于或等于 42,如下所示,
URUNDI,VIET-NAM - DEMOCRATIC REPUBLIC OF
AFGHANISTAN,WEST GERMANY,ALAND ISLANDS
目的是用尽可能少的行容纳所有单词。
【问题讨论】:
【参考方案1】:您的问题是bin-packing problem 的变体。这是一个 NP 难题,因此除非您的输入非常小,否则试图找到最佳解决方案可能并不可行。
有几种方法可以解决:
您可以选择first-fit greedy algorithm(易于实施,在许多情况下可以提供不错的结果)。这是问题的 2 近似值,因此在最坏的情况下,您的行数将是最佳解决方案的两倍。
您还可以实现蛮力算法(使用枚举算法测试所有可能的组合,只适合非常小的输入但找到最佳解决方案)。
使用 java 的另一种可能性是使用Ilog 之类的接口将其插入Cplex solver(或任何其他ILP 求解器)。
恕我直言,ILP 方法应该受到青睐,因为它是学习使用的有用工具,一旦你完成了接口部分,程序编写起来会非常简单,而且它已经过优化,会给你返回一个小型实例的最佳答案,以及不可处理的实例的良好可行解决方案。
【讨论】:
以上是关于重新排列单词以在一行中容纳最多单词并使用 Java 创建更少的行数的主要内容,如果未能解决你的问题,请参考以下文章
华为OD机试 2023最新 字符串重新排列字符串重新排序(C++ 100%)
华为机试真题 C++ 实现字符串重新排列2022.11 Q4新题
华为机试真题 C++ 实现字符串重新排列2022.11 Q4新题