【问题标题】:Rename the Repeated Values in array c#重命名数组c#中的重复值
【发布时间】:2014-03-18 07:11:40
【问题描述】:

我有一个如下所示的数组:-

a[53]={ARPNUM-T,
OR1PATTYP-T,
IVNUM-T,
IVDESC-T,
ORDEPT-T,
ARPNAME-T,
ARGNAME-T,
ARPATADDR1-T,
ARPATCITY-T,
ARPATSTATE-T,
ARPATZIP-N,
ARSEX-T,
ARBIRTH-N,
ARSSN-T,
ARMARRY-T,
ARADMDT-N,
ARDISDT-N,
ARPEMP-T,
ARPHY1-T,
ARPHYNM1-T,
ARMRNUM-T,
ARGUARSSN-T,
ARPHONE-T,
AREMPLYR-T,
ARADDR1-T,
ARSTATE-T,
ARZIP-N,
ARPATPHONE-N,
ARDIAG01-T,
ISSUBNAME-T,
ISCOMPCD-T,
ISCONAME-T,
ISCONTRAC-T,
ISGROUP-T,
ISPRIMARY-T,
ISCOADDR-N,
ISCOCITST-T,
ISPATREL-T,
ISCERTNO-T,
ISCOZIP-N,
ISSUBNAME-T,
ISCOMPCD-T,
ISCONAME-T,
ISCONTRAC-T,
ISGROUP-T,
ISPRIMARY-T,
ISCOADDR-N,
ISCOCITST-T,
ISPATREL-T,
ISCERTNO-T,
ISCOZIP-N,
ARCITY-T}

有一些重复的值,例如 ISSUBNAME-T,ISCOMPCD-T。

我需要将数组 a 填充到数组 b

其中重复值会以重复次数为后缀,

例如 - 如果 ISSUBNAME-T 重复 3 次,则 ISSUBNAME-T_3

我试过一个代码:-

for (int d = 1; d < 53; d++)
            {

                b[0] = a[0];
                for (int k = 1; k < d; k++)
                {
                    int count = 0;
                    //b[d] = a[d];
                    if (a[d] == a[d - k])
                    {
                        count++;


                        if (count > 0)
                        {
                            b[d] = a[d] + "_" + count + "";
                        }
                        else
                        {
                            b[d] = a[d];
                        }

                        //Console.WriteLine(count);
                    }
                    //Console.WriteLine(count);




                }

                //Console.WriteLine(count);


            }

但它没有显示正确的输出。

【问题讨论】:

  • “它没有显示正确的输出”永远是不够的信息。它做什么?如果您创建一个简短但完整的程序来演示该问题(我建议使用较小的输入)并格式化您的代码更具可读性,那么帮助您也会容易得多。
  • 对不起数组的长度和一切..我的问题是数组的元素是否重复程序应该计算它的重复次数并将其后缀到另一个数组“b”,这样如果 1 个元素重复 3 次,则第一个重复的元素将是 element_1 和 element_2 、element_3 等等。
  • 是的,但你还没有说你当前的代码实际上做了什么。你说过它不起作用,但这并没有描述它的作用。正如我之前所说,您可以使您的问题变得更好:修复格式,减少输入大小,并将其放在一个简短但完整的程序的形式中。然后,您可以显示所需的输出和当前的输出。
  • 当然我现在就在做...

标签: c# arrays algorithm


【解决方案1】:

按值对数组项进行分组。然后检查组是否包含多个项目。如果是,则返回格式化的项目值,否则简单地返回项目值:

string[] b = a.GroupBy(i => i)
              .Select(g => g.Count() > 1 ?
                           String.Format("{0}_{1}", g.Key, g.Count()) : g.Key)
              .ToArray();

查询语法(很容易只计算一次组长度):

var query =  from i in a
             group i by i into g
             let count = g.Count()
             select count > 1 ? String.Format("{0}_{1}", g.Key,count) : g.Key;

string[] b = query.ToArray();

更新:如果您想保留所有项目并具有增量后缀

string[] b = a.GroupBy(e => e)
              .SelectMany(g => g.Count() == 1 ?
                               g.Take(1) :
                               g.Select((e,i) => String.Format("{0}_{1}", e,i+1))
              .ToArray();

更新 2:如果您还想保留原始顺序,那么简单的循环和字典会更简单

string[] b = new string[a.Length];
var duplicatedItems = a.GroupBy(a => a)
                       .Where(g => g.Count() > 0)
                       .ToDictionary(g => g.Key, g => g.Count());

for(int i = b.Length - 1; i >= 0 ; i--)
{
    string item = a[i];
    if (!duplicatedItems.ContainsKey(item))
    {
        b[i] = item;
        continue;
    }

    b[i] = String.Format("{0}_{1}", item, duplicatedItems[item]);
    duplicatedItems[item]--;       
}

用于比较的 Linq 查询

string[] b = 
    a.Select((e,i) => new { Item = e, Index = i })
     .GroupBy(x => x.Item)                  
     .SelectMany(g => g.Count() == 1 ?
                      g.Take(1) :
                      g.Select((x,i) => new { 
                            Item = String.Format("{0}_{1}", x.Item, i+1), 
                            Index = x.Index
                      }))
     .OrderBy(x => x.Index)
     .Select(x => x.Item)
     .ToArray();

【讨论】:

  • 2 件事:b 的大小小于 a ieblength = 42,而 a=53 并且后缀以 _2 开头,但应该是 _1,因为它只重复一次。
  • k 我通过在查询中给出 count-1 来纠正后缀,但 b 的大小小于 a 的大小,这是一个问题
  • @VivekSaurav 我认为您需要具有相同项目数后缀的单个项目。现在很清楚你想要什么。更新答案
  • 唯一的问题是当与输入数组元素检查时,输出数组元素的顺序不正确。
  • :非常感谢您的时间和耐心
猜你喜欢
  • 2012-05-25
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多