英文:
Fast way to sort a list of enum with values
问题
SOLUTION FOUND!
我正在尝试找到一种实现这段代码的方法。
我需要做的是找到快速的方法来重新排列数组,以便所有的cheese物品成为数组的第一部分,所有的milk物品在数组的中间,而bread物品位于末尾。
有什么帮助吗?
public class Shop {
enum shoppingList {cheese, milk, bread};
public static void rearrange (shoppingList[] shopping) {
shoppingList cheese = shoppingList.cheese;
shoppingList milk = shoppingList.milk;
shoppingList bread = shoppingList.bread;
}
}
英文:
SOLUTION FOUND!
I'm trying to find a way how to implement this code.
What I need to do is to find fast methods to rearrange the array, so that all cheese objects would be a part of the first part of the array and all milk objects are in the middle of the array and bread objects are at the end.
Any help here?
public class Shop {
enum shoppingList {cheese, milk, bread};
public static void rearrange (shoppingList[] shopping) {
shoppingList cheese = shoppingList.cheese;
shoppingList milk = shoppingList.milk;
shoppingList bread = shoppingList.bread;
}
}
答案1
得分: 2
由于您只有枚举,从技术上讲,枚举没有对象标识,可以表示为整数,因此通常的比较排序(例如快速排序)不是最佳方法,因为它的效率不会比O(n log n)
更好。
非比较排序会更快(例如基数排序将是O(w n)
),但在这个问题中,您只有两个不同的值,所以可以在单次数组遍历中完成排序,时间复杂度为O(n)
。
您可以实现以下步骤:
-
使用计数器
i
遍历数组。 -
每次遇到牛奶时,将其与数组中最后一个不是牛奶的元素交换。
-
通过在计数器
j
中存储末尾有多少个牛奶元素来记录末尾有多少个牛奶元素。 -
当
i
达到j
时停止。
因此,代码可能类似于:
enum Food { MILK, CHEESE };
void sortMilkLast(Food[] arr) {
int i = 0;
int j = arr.length - 1;
while (j >= 0 && arr[j] == MILK) {
j--; // 避免交换已经在正确位置的牛奶元素
}
while (i <= j) {
if (arr[i] == MILK) {
arr[i] = arr[j]; // 这应该始终是CHEESE
arr[j] = MILK;
j--;
while (j >= 0 && arr[j] == MILK) {
j--; // 避免交换已经在正确位置的牛奶元素
}
}
i++;
}
}
请记住,复杂度并不等于性能,对于小数组(例如5个元素),不同方法的差异在排序时间上会有很小的影响。
英文:
Since you have only enums, which technically don't have object identity and can be represented as integers, the usual comparative sort e.g. Quicksort is not the best approach as it won't be better than O(n long n)
.
A non-comparative sort will be faster (e.g. Radix Sort will be O(w n)
) but in this problem you only have two distinct values so sorting can be done in single array pass with O(n)
.
You can implement it as:
-
Iterate over the array with a counter
i
. -
Each time you spot a milk swap it with the last element in the array which is not milk.
-
Remember how many elements at the end are milk by storing it in a counter
j
. -
Stop when
i
reachesj
.
So it could be something like:
enum Food { MILK, CHEESE };
void sortMilkLast(Food[] arr) {
int i = 0;
int j = arr.length - 1;
while (j >= 0 && arr[j] == MILK) {
j--; // avoid swapping MILK already in place
}
while (i <= j) {
if (arr[i] == MILK) {
arr[i] = arr[j]; // this should always be a CHEESE
arr[j] = MILK;
j--;
while (j >= 0 && arr[j] == MILK) {
j--; // avoid swapping MILK already in place
}
}
i++;
}
}
Remember that complexity is not performance and for small arrays (e.g. 5 elements) the difference in approach will make little difference in sorting time.
答案2
得分: 0
这个算法在数组仅包含2个不同元素时才能在O(n)时间内运行。首先,你需要将这两个不同的元素转换为0或1。
//驱动程序
public static void main(String[] args) {
int arrOfValues[] = { 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1 };
sortArray(arrOfValues, arrOfValues.length);
//打印数组
for (int loopInt : arrOfValues) {
System.out.print(loopInt + " ");
}
}
static void sortArray(int arr[], int n) {
int valueFor0 = 0;
int valueFor1 = n - 1;
while (valueFor0 < valueFor1) {
if (arr[valueFor0] == 1) {
// 交换类型0和类型1
arr[valueFor0] = arr[valueFor0] + arr[valueFor1];
arr[valueFor1] = arr[valueFor0] - arr[valueFor1];
arr[valueFor0] = arr[valueFor0] - arr[valueFor1];
valueFor1--;
} else {
valueFor0++;
}
}
}
英文:
This algorithm works in O(n) if and only if the array contains 2 distinct elements. First,
you should convert the two distinct elements to 0 or 1.
//Driver
public static void main(String[] args) {
int arrOfValues[] = { 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1 };
sortArray(arrOfValues, arrOfValues.length);
//print array
for (int loopInt : arrOfValues) {
System.out.print(loopInt + " ");
}
}
static void sortArray(int arr[], int n) {
int valueFor0 = 0;
int valueFor1 = n - 1;
while (valueFor0 < valueFor1) {
if (arr[valueFor0] == 1) {
// swap type0 and type1
arr[valueFor0] = arr[valueFor0] + arr[valueFor1];
arr[valueFor1] = arr[valueFor0] - arr[valueFor1];
arr[valueFor0] = arr[valueFor0] - arr[valueFor1];
valueFor1--;
} else {
valueFor0++;
}
}
}
答案3
得分: 0
public static void rearrange (shoppingList[] shopping) {
int cheesePos = 0;
int n = shopping.length;
// move all cheese to the start
for (int i = 0; i < n; i++) {
if (shopping[i] == shoppingList.cheese) {
shopping[cheesePos++] = shoppingList.cheese;
}
}
// fill the rest with milk
while (cheesePos < n) {
shopping[cheesePos++] = shoppingList.milk;
}
}
英文:
It appears here cheese
values needs to be moved to the start of array and as long as only two values are used here, rearrange
method may be written as:
public static void rearrange (shoppingList[] shopping) {
int cheesePos = 0;
int n = shopping.length;
// move all cheese to the start
for (int i = 0; i < n; i++) {
if (shopping[i] == shoppingList.cheese) {
shopping[cheesePos++] = shoppingList.cheese;
}
}
// fill the rest with milk
while (cheesePos < n) {
shopping[cheesePos++] = shoppingList.milk;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论