英文:
How to rotate a String of space delimited integers in Java?
问题
假设我有以下字符串:"10 30 20 12 34"
。现在我想要旋转这个字符串,但保持第一个和最后一个整数不变。所以我应该得到以下3个输出:
10 20 30 12 34
10 30 12 20 34
10 12 20 30 34
现在,我试图首先将这个字符串转换为一个int[]数组,使其看起来像[10, 30, 20, 12, 34]
,然后创建另一个数组,获取原始数组的每个元素并将它们插入新数组。
这是我目前为止的代码:
String[] arr1 = tree.getPreOrder().split("" ");
int[] arr2 = new int[5];
arr2[0] = Integer.parseInt(arr1[0]);
arr2[1] = Integer.parseInt(arr1[3]);
arr2[2] = Integer.parseInt(arr1[2]);
arr2[3] = Integer.parseInt(arr1[1]);
arr2[4] = Integer.parseInt(arr1[4]);
我的问题是,如何将arr2
转换为格式10 12 20 30 34
。我尝试使用join()
,但它不起作用。
此外,是否有一种更简单的方法来实现我正在尝试做的事情,因为目前我是在对这些值进行硬编码。
更新
我创建了一个方法,现在基本上旋转了中间值。然而,我遇到了一个问题,其中一个随机生成的字符串与原始字符串相同,我想避免这种情况。我基本上只想生成与原始字符串完全不同的3个变体,如果这有助于解决问题。
这是我的更新后的代码:
static String randomizeAnswer(String ans) {
String[] arr = ans.split("" ");
int arraySize = arr.length;
String firstElement = arr[0];
String lastElement = arr[arraySize - 1];
String[] arr2 = new String[arraySize - 2];
String arr3[] = new String[arraySize];
arr3[0] = firstElement;
for (int i = 0; i < arraySize - 2; i++) {
arr2[i] = arr[i + 1];
}
Collections.shuffle(Arrays.asList(arr2));
for (int j = 0; j < arr2.length; j++) {
arr3[j + 1] = arr2[j];
}
arr3[arraySize - 1] = lastElement;
return String.join(" ", arr3);
}
for (int i = 0; i < 3; i++) {
System.out.println(randomizeAnswer("10 30 20 12 34"));
}
更新 2
最终,我成功制作了一个解决方案,但是下面 @WJS 给出的答案要好得多。
static String randomizeAnswer(String ans) {
String[] arr = ans.split("" ");
int arraySize = arr.length;
String firstElement = arr[0];
String lastElement = arr[arraySize - 1];
String[] arr2 = new String[arraySize - 2];
String arr3[] = new String[arraySize];
arr3[0] = firstElement;
for (int i = 0; i < arraySize - 2; i++) {
arr2[i] = arr[i + 1];
}
Collections.shuffle(Arrays.asList(arr2));
for (int j = 0; j < arr2.length; j++) {
arr3[j + 1] = arr2[j];
}
arr3[arraySize - 1] = lastElement;
return String.join(" ", arr3);
}
static String[] generateAnswers(String ans) {
String[] answers = new String[5];
answers[0] = ans;
answers[4] = "None of the answers are correct";
for (int x = 0; x < 3; x++) {
while (true) {
String randomAns = randomizeAnswer(ans);
if (Arrays.stream(answers).anyMatch(randomAns::equals)) {
continue;
} else {
answers[x + 1] = randomAns;
break;
}
}
}
return answers;
}
英文:
Suppose I have the following String: "10 30 20 12 34"
. Now I want to rotate the String but keep the first and last integers fixed. So I should get the 3 outputs should be as follows:
10 20 30 12 34
10 30 12 20 34
10 12 20 30 34
Now, I am trying to first convert the String into an int[] array such that it looks like [10, 30,20, 12, 34]
and then create another array, get each element of the original array and insert them in the new array.
This is what I have so far:
String[] arr1 = tree.getPreOrder().split(" ");
int[] arr2 = new int[5];
arr2[0] = Integer.parseInt(arr1[0]);
arr2[1] = Integer.parseInt(arr1[3]);
arr2[2] = Integer.parseInt(arr1[2]);
arr2[3] = Integer.parseInt(arr1[1]);
arr2[4] = Integer.parseInt(arr1[4]);
My issue is, how do I now convert arr2
into the format 10 12 20 30 34
. I tried to use join()
but it doesn't work.
Also, is there a simpler way to do what I'm trying to do as currently, I am hard coding those values.
Thanks
UPDATE
I created a method which basically rotates the middle values now. However, I got into an issue where one randomly generated String was the same as the original and I would like to avoid that. I'm basically trying to generate only exactly 3 variations of the original string if that helps.
Here's my updated code:
static String randomizeAnswer(String ans) {
String[] arr = ans.split(" ");
int arraySize = arr.length;
String firstElement = arr[0];
String lastElement = arr[arraySize - 1];
String[] arr2 = new String[arraySize - 2];
String arr3[] = new String[arraySize];
arr3[0] = firstElement;
for (int i = 0; i < arraySize - 2; i++) {
arr2[i] = arr[i + 1];
}
Collections.shuffle(Arrays.asList(arr2));
for (int j = 0; j < arr2.length; j++) {
arr3[j + 1] = arr2[j];
}
arr3[arraySize - 1] = lastElement;
return String.join(" ", arr3);
}
for int(i = 0; i<3; i++){
System.out.println(randomizeAnswer("10 30 20 12 34"));
}
UPDATE 2
I eventually managed to make a solution which works but the answer by @WJS below is much better.
static String randomizeAnswer(String ans) {
String[] arr = ans.split(" ");
int arraySize = arr.length;
String firstElement = arr[0];
String lastElement = arr[arraySize - 1];
String[] arr2 = new String[arraySize - 2];
String arr3[] = new String[arraySize];
arr3[0] = firstElement;
for (int i = 0; i < arraySize - 2; i++) {
arr2[i] = arr[i + 1];
}
Collections.shuffle(Arrays.asList(arr2));
for (int j = 0; j < arr2.length; j++) {
arr3[j + 1] = arr2[j];
}
arr3[arraySize - 1] = lastElement;
return String.join(" ", arr3);
}
static String[] generateAnswers(String ans) {
String[] answers = new String[5];
answers[0] = ans;
answers[4] = "None of the answers are correct";
for (int x = 0; x < 3; x++) {
while (true) {
String randomAns = randomizeAnswer(ans);
if (Arrays.stream(answers).anyMatch(randomAns::equals)) {
continue;
} else {
answers[x+1] = randomAns;
break;
}
}
}
return answers;
}
答案1
得分: 1
将数组转换为整数。请注意,字符串值可以在不解析为整数的情况下进行旋转。
String str = "10 30 20 12 34";
int[] vals = Arrays.stream(str.split("\\s+"))
.mapToInt(Integer::parseInt).toArray();
要旋转的范围
int start = 1;
int end = 4; // 独占
用于保存旋转后的值数组的数组。
String[] results = new String[end - start];
现在对它们进行旋转,转换为字符串并存储。请注意,先前旋转过的数组需要反馈到方法中。但是该数组不会改变,因为它在旋转方法中被复制了。
for (int i = 0; i < end - start; i++) {
vals = rotate(vals, start, end);
// 转换为字符串 - 不能使用join,因为这些不是字符串。
// 这只是将结果流化,转换为字符串,并将它们连接成一个字符串。
results[i] =
Arrays.stream(vals).mapToObj(v -> Integer.toString(v))
.collect(Collectors.joining(" "));
}
for (String rotated : results) {
System.out.println(rotated);
}
打印结果
10 20 12 30 34
10 12 30 20 34
10 30 20 12 34
这只是在指定的范围内将数组向左旋转一个位置。它首先复制了原始数组。请注意,end
是独占的。
public static int[] rotate(int[] arr, int start, int end) {
arr = Arrays.copyOf(arr, arr.length);
int v = arr[start];
for (int i = start; i < end-1; i++) {
arr[i] = arr[i+1];
}
arr[end-1] = v;
return arr;
}
英文:
Convert the array to ints. Note that the string values could be rotated without parsing to an int.
String str = "10 30 20 12 34";
int[] vals = Arrays.stream(str.split("\\s+"))
.mapToInt(Integer::parseInt).toArray();
The range to rotate
int start = 1;
int end = 4; // exclusive
An array to save the rotated array of values.
String[] results = new String[end - start];
And now rotating them, converting to a string and storing. Note that the previously rotated array needs to be fed back into the method. But that array is not changed because it is copied in the rotate method.
for (int i = 0; i < end - start; i++) {
vals = rotate(vals, start, end);
// convert to String - can't use join since these are not strings.
// this just streams the results, converts to a string, and joins them into
// a single string.
results[i] =
Arrays.stream(vals).mapToObj(v -> Integer.toString(v))
.collect(Collectors.joining(" "));
}
for (String rotated : results) {
System.out.println(rotated);
}
prints
10 20 12 30 34
10 12 30 20 34
10 30 20 12 34
This simply rotates the array one cell to the left within the specified range. It first makes a copy of the original array. Note the end
is exclusive.
public static int[] rotate(int[] arr, int start, int end) {
arr = Arrays.copyOf(arr, arr.length);
int v = arr[start];
for (int i = start; i < end-1; i++) {
arr[i] = arr[i+1];
}
arr[end-1] = v;
return arr;
}
</details>
# 答案2
**得分**: 1
这里是使用Java Streams的我的个人见解。
```java
private static int[] rotate(int[] array, int count) {
if (array.length >= 0 && array.length <= 2) {
return array;
}
return IntStream.range(0, array.length)
.map(i -> (i == 0 || i == array.length - 1) ? i : (i - 1 + count) % (array.length - 2) + 1)
.map(i -> array[i])
.toArray();
}
这会将给定的数组向右旋转* count
个位置,但保持第一个和最后一个索引不变。例如,当 count = 1
*时,数组[10, 30, 20, 12, 34]
变为[10, 12, 30, 20, 34]
。
如果您想要生成* n
*个随机序列,您可以使用下面的代码片段。这将生成与原始数组不相等的数组。
int array = { ... };
int n = 2;
ThreadLocalRandom.current().ints(n, 1, array.length - 2)
.mapToObj(randomInt -> rotate(array, randomInt))
.forEach(result -> System.out.println(Arrays.toString(result)));
// 或者,如果您想将其转换回字符串:
//.collect(Collectors.mapping(String::valueOf, Collectors.joining(" ")));
Collections::shuffle
当然,您还可以使用Collections::shuffle
和List::subList
来简单地对除第一个和最后一个元素以外的元素进行洗牌。这个方法是通用的,所以实际上元素是否是整数并不重要。例如,使用Arrays.asList("10 30 20 12 34".split(" "))
会产生一个List<String>
。
public static <T> List<T> shuffleMid(List<T> list) {
List<T> newList = new ArrayList<>(list);
do {
Collections.shuffle(newList.subList(1, newList.size() - 1));
} while (newList.equals(list)); // 确保它与原始列表不相等
return newList;
}
do-while
循环确保洗牌后的列表不等于原始列表。这可能是一个天真的实现。
英文:
Here's my two cents using Java Streams.
private static int[] rotate(int[] array, int count) {
if (array.length >= 0 && array.length <= 2) {
return array;
}
return IntStream.range(0, array.length)
.map(i -> (i == 0 || i == array.length - 1) ? i : (i - 1 + count) % (array.length - 2) + 1)
.map(i -> array[i])
.toArray();
}
This rotates the given array count
positions to the right, but leaves the first and last indexes unharmed. For example, when count = 1
, the array [10, 30, 20, 12, 34]
becomes [10, 12, 30, 20, 34]
.
If you want to generate an n
number of random sequences, you could use the snippet below. This generates arrays which are not equal to the original array.
int array = { … };
int n = 2;
ThreadLocalRandom.current().ints(n, 1, array.length - 2)
.mapToObj(randomInt -> rotate(array, randomInt))
.forEach(result -> System.out.println(Arrays.toString(result)));
// Or, if you want to convert it back to a String:
//.collect(Collectors.mapping(String::valueOf, Collectors.joining(" ")));
Collections::shuffle
Of course, you can also simply shuffle the elements minus the first and last ones using Collections::shuffle
and List::subList
. This method is generic, so it really does not matter whether the elements are actually integers or not. For instance, a List<String>
is yielded with Arrays.asList("10 30 20 12 34".split(" "))
.
public static <T> List<T> shuffleMid(List<T> list) {
List<T> newList = new ArrayList<>(list);
do {
Collections.shuffle(newList.subList(1, newList.size() - 1));
} while (newList.equals(list)); // Make sure it is unequal to the original
return newList;
}
The do-while loop makes sure the shuffled list is not equal to the original list. This may be a naive implementation.
答案3
得分: 1
以下是翻译好的部分:
另一个示例:
public static void main(String[] args) {
String treePreOrder = "10 30 20 12 34";
String rot1 = rotateMiddle(treePreOrder);
String rot2 = rotateMiddle(rot1);
System.out.println(treePreOrder);
System.out.println(rot1);
System.out.println(rot2);
}
public static String rotateMiddle(String values) {
String[] arr = values.split(" ");
if (arr.length >= 4) {
String temp = arr[1];
for(int i=1; i<=(arr.length-3); i++) {
arr[i] = arr[i+1];
}
arr[arr.length-2] = temp;
}
return String.join(" ", arr);
}
输出:
10 30 20 12 34
10 20 12 30 34
10 12 30 20 34
请注意,代码部分已经被保留,没有翻译。
英文:
Another example:
public static void main(String[] args) {
String treePreOrder = "10 30 20 12 34";
String rot1 = rotateMiddle(treePreOrder);
String rot2 = rotateMiddle(rot1);
System.out.println(treePreOrder);
System.out.println(rot1);
System.out.println(rot2);
}
public static String rotateMiddle(String values) {
String[] arr = values.split(" ");
if (arr.length >= 4) {
String temp = arr[1];
for(int i=1; i<=(arr.length-3); i++) {
arr[i] = arr[i+1];
}
arr[arr.length-2] = temp;
}
return String.join(" ", arr);
}
Output:
10 30 20 12 34
10 20 12 30 34
10 12 30 20 34
答案4
得分: 0
以下是翻译好的内容:
使用另一个辅助数组:
String in = "10 30 20 12 34";
String[] arr_in = in.split(" ");
String[] arr_out = new String[arr_in.length];
arr_out[0] = arr_in[0];
arr_out[arr_out.length-1] = arr_in[arr_in.length-1];
for(int i=arr_in.length-2, j=1; i>0; i--,j++) {
arr_out[j] = arr_in[i];
}
// 打印输出:
for(int i=0; i<arr_out.length; i++) {
System.out.println(arr_out[i]);
}
原地旋转:
public static void main(String[] args) {
String in = "10 30 20 12 34";
String[] arr = in.split(" ");
String tmp;
for(int i=arr.length-2, j=1; i>(arr.length/2); i--,j++) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 打印输出:
for(int i=0; i<arr.length; i++) {
System.out.println(arr[i]);
}
}
英文:
To rotate the elements (except the first and last elements) you can use this:
-
- use another helping array:
String in = "10 30 20 12 34";
String[] arr_in = in.split(" ");
String[] arr_out = new String[arr_in.length];
arr_out[0] = arr_in[0];
arr_out[arr_out.length-1] = arr_in[arr_in.length-1];
for(int i=arr_in.length-2, j=1; i>0; i--,j++)
{
arr_out[j] = arr_in[i];
}
// print:
for(int i=0; i<arr_out.length;i++)
{
System.out.println(arr_out[i]);
}
-
- in place :
public static void main(String[] args) {
String in = "10 30 20 12 34";
String[] arr = in.split(" ");
String tmp;
for(int i=arr_in.length-2, j=1; i>(arr_in.length/2); i--,j++)
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// print:
for(int i=0; i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
答案5
得分: 0
String[] array = new String[5];
for(int i = 0; i < 5; i++)
array[i] = i + 1 + "";
//array[0] = 1, array[1] = 2, array[3] = 3, array[4] = 4, array[5] = 5
int first = 0;
int last = array.length - 1;
for(int i = 1; i < array.length / 2; i++){
first = i;
last = array.length - i - 1;
String aux = array[first];
array[first] = array[last];
array[last] = aux;
first++;
last--;
}
for(int i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
输出将会是:1 4 3 2 5
英文:
String[] array = new String[5];
for(int i = 0; i < 5; i++)
array[i] = i + 1 + "";
//array[0] = 1, array[1] = 2, array[3] = 3, array[4] = 4, array[5] = 5
int first = 0;
int last = array.length - 1;
for(int i = 1; i < array.length / 2; i++){
first = i;
last = array.length - i - 1;
String aux = array[first];
array[first] = array[last];
array[last] = aux;
first++;
last--;
}
for(int i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
The output will be: 1 4 3 2 5
答案6
得分: 0
这绝对有一种更好的方法来利用JDK中的其他API... 但以下是我想出来的方法。
// 根据 [direction] 左/右移 [direction] 个位置。到目前为止,不会抛出 IndexOutOfBoundsException 异常 :)
private static int[] shift(int[] values, int direction) {
int[] result = new int[values.length];
for (int i = 0; i < result.length; i++) {
result[i] = values[(values.length + (i + direction % values.length)) % values.length];
}
return result;
}
public static void main(String[] args) {
int[] values = new int[]{101, 1, 2, 3, 100};
int[] middleValues = Arrays.copyOfRange(values, 1, values.length-1);
int[][] allCombos = new int[middleValues.length][values.length];
int shiftPtr = 0;
for (int[] row : allCombos) {
row[0] = values[0];
row[row.length-1] = values[values.length-1];
int[] shifted = shift(middleValues, shiftPtr);
for (int i = 0; i < middleValues.length; i++) {
row[i + 1] = shifted[i];
}
shiftPtr++;
// 并打印测试结果...
System.out.println(Arrays.toString(row));
}
}
然后你会得到以下输出:
> [101, 1, 2, 3, 100]
> [101, 2, 3, 1, 100]
> [101, 3, 1, 2, 100]
英文:
There most definitely is a better way to leverage other APIs in the JDK... but here is what I came up with.
// shifts by [direction] spaces (-ve and +ve) for left/right. So far so good with not throwing IndexOutOfBoundsExceptions :)
private static int[] shift(int[] values, int direction) {
int[] result = new int[values.length];
for (int i = 0; i < result.length; i++) {
result[i] = values[(values.length + (i + direction % values.length)) % values.length];
}
return result;
}
public static void main(String[] args) {
int[] values = new int[]{101, 1, 2, 3, 100};
int[] middleValues = Arrays.copyOfRange(values, 1, values.length-1);
int[][] allCombos = new int[middleValues.length][values.length];
int shiftPtr = 0;
for (int[] row : allCombos) {
row[0] = values[0];
row[row.length-1] = values[values.length-1];
int[] shifted = shift(middleValues, shiftPtr);
for (int i = 0; i < middleValues.length; i++) {
row[i + 1] = shifted[i];
}
shiftPtr++;
// and print out to test...
System.out.println(Arrays.toString(row));
}
}
And you end up with this output....
> [101, 1, 2, 3, 100]
> [101, 2, 3, 1, 100]
> [101, 3, 1, 2, 100]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论