在整数数组的末尾移动重复的数字

时间:2015-10-09 06:06:13

标签: c#

我想像这样移动数组末尾的所有重复数字。

{4,1,5,4,3,1,6,5}

{4,1,5,3,6,4,1,5} 我也想知道重复的数量。我将用于调整数组大小。 这是我尝试的代码,但是当我在开始时插入超过2个重复时,此代码不兼容。

static void RemoveRepeated(ref int[] array)
    {
        int count = 0; bool flag;
        for (int i = 0; i < array.Length; i++)
        {
            flag = true;
            for (int j = i+1; j < array.Length-1; j++)
            {
                if (array[i] == array[j] )
                {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        if (flag)
                        {
                            count++;
                            flag = false;
                        }
                }
            }
        }
        Array.Resize(ref array,array.Length-count);
    }

提前致谢:)

6 个答案:

答案 0 :(得分:2)

一个好的解决方案是使用适合的数据结构。它不会修复您的算法但会替换它。这里HashSet<T>是完美的。 HashSet<T>删除所有重复的内容。查看msdn以获取更多信息。

Demo on .NETFiddle

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var array = new int[]{ 4,1,5,4,3,1,6,5 };

        RemoveRepeated(ref array);

        foreach (var item in array)
            Console.WriteLine(item);
    }

    static void RemoveRepeated(ref int[] array)
    {
        array = new HashSet<int>(array).ToArray();
    }
}

顺便说一下,你真的不需要ref。我会删除它并将void RemoveRepeated(ref int[] array)更改为int[] RemoveRepeated(int[] array)。见ref parameter or return value?

答案 1 :(得分:1)

您所做的相当于只保留原始顺序中的唯一元素。这是更简单的方法:

    static void RemoveRepeated(ref int[] array)
    {
        HashSet<int> seen = new HashSet<int>();
        List<int> newArray = new List<int>(array.Length);

        foreach(int x in array)
        {
            if(!seen.Contains(x))
            {
                seen.Add(x);
                newArray.Add(x);
            }
        }

        array = newArray.ToArray();
    }

答案 2 :(得分:0)

这里不要使用数组。您可以尝试(仅举一个示例)将List<int>Count()所有具有多个元素的组分组。计算后,您可以使用Distinct()仅获取不同的元素。

在我看来,调整像这样的数组总是一个非常糟糕的主意。

修改

好吧,就像已经说过的其他答案一样,HashSet是一种更好的方法。

答案 3 :(得分:0)

试试这个:

class Program
{
    static void Main(string[] args)
    {
        int[] ints = {4,1,5,4,3,1,6,5};

        var query = ints.GroupBy(x => x).OrderBy(x => x.Count()).Select(x => x);


        // print ordered array showing dupes are last
        query.ToList().ForEach(x => Console.WriteLine(x.Key.ToString()));

        // Get number of dupes
        int dupeCount = query.Where(x => x.Count() > 1).Count();

        // put unique items into a new array
        var newArray = query.Where(x => x.Count() == 1).Select(x => x.Key).ToArray();

        // put distinct items into an array
        var distinctArray = ints.Distinct().ToArray();

        Console.ReadKey();   
    }
}

编辑:添加了不同的元素

答案 4 :(得分:0)

如果要将重复项移动到数组的末尾(但保留顺序),可以执行以下操作:

static void RemoveRepeated(ref int[] array)
{
    var lookup = array.ToLookup(x => x);
    var maxdupes = lookup.Select(x => x.Count()).Max();

    var reordered =
        Enumerable
            .Range(0, maxdupes)
            .SelectMany(x => lookup.SelectMany(y => y.Skip(x).Take(1)))
            .ToArray();

    Array.Copy(reordered, array, reordered.Length);
}

这会将{ 4, 1, 5, 4, 3, 1, 6, 5 }变为{ 4, 1, 5, 3, 6, 4, 1, 5 }

通过这样做,您可以轻松获得重复数量:

lookup
    .Select(x => new
    {
        Value = x.Key,
        Count = x.Count(),
    });

返回:

4 2 
1 2 
5 2 
3 1 
6 1

答案 5 :(得分:0)

 class Program
{
    static void Main(string[] args)
    {
        int[] arr = new int[] { 4, 1, 5, 4, 3, 1, 6, 5 };
        RemoveRepeated(ref arr);
        foreach (int i in arr)
        {
            Console.WriteLine(i);
        }
        Console.ReadKey();
    }

    private static void RemoveRepeated(ref int[] array)
    {
        int count =0;
        for (int i = 0; i < array.Length; i++)
        {
            for (int j = i + 1; j < array.Length; j++)
            {
                if (array[i] == array[j])
                {
                    int temp = array[j];
                    count++;
                    for (int k = j; k < array.Length-1; k++)
                    {
                        array[k] = array[k + 1];
                    }
                    array[array.Length - 1] = temp;
                    j = array.Length;
                }
            }
        }
        Array.Resize(ref array, array.Length - count);
    }
}