这就是我想做的事。
我在列表中有大量的数字,但它有一个增加或减少的序列。
如, 100 200 300 400 500 600 500 400 300 200 100 500 700 800 900
让我们说这些值存储在列表或数组中。我怎么能将这些分成多个数组或由序列组成的列表。
例如,清单1:100 200 300 400 500 600 清单2:500 400 300 200 100 清单3:500 700 800 900
这就是我所做的。我被卡住了。
for (int i = 0; i < p.Count - 1; i++)
{
double v = p.ElementAt(i);
if (initialP > v)
{
if (low == 1)
{
sep.Add(sep_index);
low = 0;
}
else
{
}
high = 1;
}
if (initialP < v)
{
if (high == 1)
{
sep.Add(sep_index);
high = 0;
}
low = 1;
}
initialP = v;
sep_index++;
if (i == p.Count - 2)
{
sep.Add(sep_index);
}
}
答案 0 :(得分:2)
正如评论中所建议的那样,你应该使用一个列表列表,当循环使用一个新列表时,如果在排序方向上有一个开关:
编辑:已修复以考虑相同的数字和严格的比较。
public static List<List<int>> GetLists(int[] nums, bool strict) {
List<List<int>> lists = new List<List<int>>();
List<int> list = new List<int>();
lists.Add(list);
list.AddRange(nums.Take(1));
if (nums.Length <= 1) {
return lists;
}
if (strict && nums[0] == nums[1]) {
list = new List<int>();
lists.Add(list);
list.Add(nums[1]);
}
else
list.Add(nums[1]);
if (nums.Length == 2)
{
return lists;
}
int direction = Math.Sign(nums[2] - nums[1]);
for (int i = 2; i < nums.Length; i++) {
int d = Math.Sign(nums[i] - nums[i - 1]);
if ((d == direction && (d != 0 || !strict))
|| (d != 0 && strict)
|| (Math.Abs(d + direction) == 1 && !strict))
{
list.Add(nums[i]);
if (d != 0 && direction == 0) direction = d;
}
else
{
direction = d;
list = new List<int>();
list.Add(nums[i]);
lists.Add(list);
}
}
return lists;
}
static void Main(string[] args)
{
int[] nums = new int[] { 2, 2, 2, 1, 1, 3, 3, 4, 4 };
var lists = GetLists(nums, false);
foreach (var list in lists) {
foreach (var item in list)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
/*
* Prints:
* 2 2 2 1 1
* 3 3 4 4
* */
}
答案 1 :(得分:0)
派生或旋转。如果是积极的 - 一个方向。否则 - 另一个。 使用旋转,它将显示方向(向上或向下):( n + 1 / n)。当旋转发生变化时,则将元素存储在列表中。
答案 2 :(得分:0)
我会做这样的事情:
private static List<int[]> SplitOnDirection(int[] input)
{
List<int[]> output = new List<int[]>();
List<int> currentList = new List<int>();
bool? isRaising = null;
int? previousNumber = null;
foreach (int number in input)
{
// do we have a previous value?
if (previousNumber.HasValue)
{
// only if the number is different, then we have to check the direction.
if (number != previousNumber.Value)
{
bool isHigherNumber = (number > previousNumber.Value);
// do we already know if we start with raise/lowering
if (isRaising.HasValue)
{
// if we have a higher number and we're not raising, change direction.
if (isHigherNumber != isRaising.Value)
{
// We changed direction..
output.Add(currentList.ToArray());
currentList = new List<int>();
}
}
isRaising = isHigherNumber;
}
}
previousNumber = number;
currentList.Add(number);
}
// if we didn't changed direction, we should 'flush' these.
if (currentList.Count > 0)
output.Add(currentList.ToArray());
return output;
}
int[] input = new int[] { 100, 200, 300, 400, 500, 600, 500, 400, 300, 200, 100, 500, 700, 800, 900 };
List<int[]> output = SplitOnDirection(input);
答案 3 :(得分:0)
可能的解决方案:
public static IList<IList<int>> UpDownSeparator(IEnumerable<int> value) {
if (Object.ReferenceEquals(null, value))
throw new ArgumentNullException("value");
List<IList<int>> result = new List<IList<int>>();
List<int> current = new List<int>();
result.Add(current);
// +1 - asceding, -1 - descending, 0 - to be determined later
int direction = 0;
foreach(int item in value) {
if (direction == 0) {
if (current.Count > 0) {
if (item > current[current.Count - 1])
direction = 1;
else if (item < current[current.Count - 1])
direction = -1;
}
current.Add(item);
}
else if (direction < 0) {
if (item > current[current.Count - 1]) {
direction = 1;
current = new List<int>() { item };
result.Add(current);
}
else
current.Add(item);
}
else {
if (item < current[current.Count - 1]) {
direction = -1;
current = new List<int>() { item };
result.Add(current);
}
else
current.Add(item);
}
}
return result;
}
....
List<int> list = new List<int>() { 100, 200, 300, 400, 500, 600, 500, 400, 300, 200, 100, 500, 700, 800, 900};
// [[100, 200, 300, 400, 500, 600], [500, 400, 300, 200, 100], [500, 700, 800, 900]]
IList<IList<int>> result = UpDownSeparator(list);
答案 4 :(得分:0)
大约20分钟,但我会在下面做这样的事情。使用Java,我确信可以使用其他语言语法轻松编写。
Input
1, 1, 1, -1, 2, 3, 4, 4, 4, 5, 6, 5, 4, 4, 3, 3, 6, 6, 2, 1, 5, 7, 8, 9
Output
1 1 1 -1
2 3 4 4 4 5 6
5 4 4 3 3
6 6
2 1
5 7 8 9
代码
public static void main(String[] args) {
int[] input = new int[]{1, 1, 1, -1, 2, 3, 4, 4, 4, 5, 6, 5, 4, 4, 3, 3, 6, 6, 2, 1, 5, 7, 8, 9};
List<List<Integer>> lists = split(input);
for (List<Integer> list : lists) {
for (Integer integer : list) {
System.out.print(integer+" ");
}
System.out.println("");
}
}
public static List<List<Integer>> split(int[] input) {
List<List<Integer>> listOfList = new ArrayList<List<Integer>>();
if(input.length >= 1) {
List<Integer> list = newList(listOfList, input[0]);
Order lastO = null;
int last = input[0];
for (int i = 1; i < input.length; i++) {
Order currentO = Order.getOrder(input[i], last);
boolean samePattern = Order.sameDirection(currentO, lastO);
if(lastO == null || samePattern) {
list.add(input[i]);
} else {
list = newList(listOfList, input[i]);
lastO = null;
}
if(currentO != Order.Equal){
lastO = currentO;
}
last = input[i];
}
}
return listOfList;
}
private static List<Integer> newList(List<List<Integer>> listOfList, int element) {
List<Integer> list = new ArrayList<Integer>();
listOfList.add(list);
list.add(element);
return list;
}
private static enum Order {
Less, High, Equal;
public static Order getOrder(int first, int second) {
return first > second ? High : first < second ? Less : Equal;
}
public static boolean sameDirection(Order current, Order last) {
if(last == Order.Less && (current == Order.Less || current == Order.Equal)) {
return true;
} else if(last == Order.High && (current == Order.High || current == Order.Equal)) {
return true;
}
return false;
}
}