从列表中删除重复项,并根据项目的初始位置创建一个新列表

时间:2019-04-20 05:59:38

标签: c# algorithm list math

我有一个n项(对象)的列表,这些项已根据列出的顺序进行了加权,而权重较高的是列表中的第一项。 有些项目是重复的,因此我尝试将该项目的一个实例留在列表中,并根据权重的平均值将其分配到列表中的某个位置,例如:(ItemA_weight1 + ItemA_weight 2+ ... / Amount列表中的项目)

例如,具有以下列表:

static void iterate_test(void *node);
void delete(void *item);
static void printing(FILE *fp, const char *key, void *item);

int
main()
{   
    char *name = "name.txt";
    int *intp = malloc(sizeof(int));
    typedef void (*func1)(void*, char*, void*) = iterate_test;
    FILE *fp = fopen(name, "w");
    set_t *set = set_new(); // testing making a new set

    //Testing Iterate   
        //Function exists 
            set_iterate(set, intp, iterate_test);
        //Function doesn't exists 
            set_iterate(set, intp, iterate_test);
    //Testing Print

        //Printing normally
            set_print(set, fp, printing);
        //Printing with an inexistant function
            set_print(set, fp, printingfffff);
    //Testing Delete

        //Deleting a normal node
            set_delete(set, delete);
        //Deleteing from null set 
            set_delete(NULL, delete);
    fclose(fp);
    free(name);
    free(intp);
    return 0;
}

// Tests to see if it is able to move through the list set
static void iterate_test(void *node, char *key, void *item)
{
    if (node->key != NULL && node->item != NULL){
    }else{
    }
}

void delete(void *item)
{
    free(item);
}


/* Prints a single item */ 
static void printing(FILE *fp, const char *key, void *item)
{
  char *items = (char*)item;
  fputc('(', fp);
  fputs(key, fp);
  fputc(',', fp);
  fputs(items, fp);
  fputc(')', fp);
  fputc(',', fp);
  free(items);

项目“ a”和“ c”是重复的,因此我需要获得一个新列表,其中所有项目都是不同的,并且只有重复对象中的一个存在,因此将生成以下列表。顺便说一句,列表中的每个项目都会根据其位置和新列表中项目的总数来赋予新的权重:

新列表:

 skillsViewModel = new List<SkillViewModel>()
        {
            new SkillViewModel()
            {
                Name = "a",
                Weight = 6
            },

            new SkillViewModel()
            {
                Name = "b",
                Weight = 5
            },

            new SkillViewModel()
            {
                Name = "c",
                Weight = 4
            },
            new SkillViewModel()
            {
                Name = "a",
                Weight = 3
            },
            new SkillViewModel()
            {
                Name = "c",
                Weight = 2
            },
            new SkillViewModel()
            {
                Name = "e",
                Weight = 1
            }

        };

“ a”和“ c”的新位置的计算方法如下: 初始权重的总和,除以列表中的项数。

例如:

 skillsViewModel = new List<SkillViewModel>()
        {

            new SkillViewModel()
            {
                Name = "b",
                Weight = 4
            },

            new SkillViewModel()
            {
                Name = "c",
                Weight = 3
            },
            new SkillViewModel()
            {
                Name = "a",
                Weight = 2
            },

            new SkillViewModel()
            {
                Name = "e",
                Weight = 1
            }

        };

var averageWeight = 0; foreach (var d in dupes) { averageWeight = averageWeight + d.Weight; } "a" position = averageWeight = (int)Math.Ceiling((Decimal)averageWeight / (Decimal)skillsViewModel.Count()); =>因此四舍五入为a=1.5

与项目“ c” = 1 =>相同,因此位置1,我需要根据列表中的先前位置将其余的项目填充到列表的左侧位置。

我遇到的问题是,如果我四舍五入计算一个假人的位置,由于重量的原因,它可能与其他重复项可以得到的位置相同。

什么是实现此行为的良好通用算法,我正在使用C#?

1 个答案:

答案 0 :(得分:1)

您当前的方法有一个缺点,即属性Weight取决于上下文,但是对象本身从不“知道”其上下文,因此必须从外部设置该属性。 您已经提到的第二个缺点是:两个对象不能具有相同的位置。

您可以按权重数组对对象进行排序:

int[] weights;

weights[1][] = new SkillViewModel(){ ... }
weights[1][] = new SkillViewModel(){ ... }

weights[2][] = new SkillViewModel(){ ... }
weights[2][] = new SkillViewModel(){ ... }

通过将位置也添加为键,您仍然可以使数组更复杂但更详细(请问,我的代码可能由于语法错误,我不在C#中编程):

int[] weights;

int weights[1][] = position;
weights[1][1] = new SkillViewModel(){ ... }
weights[1][2] = new SkillViewModel(){ ... }

int weights[2][] = position;
weights[2][4] = new SkillViewModel(){ ... }
weights[2][3] = new SkillViewModel(){ ... }

具有这样的数组,PositionWeight之类的上下文在每个SkillViewModel本身内部可能是完全未知的,并且只能由属性name组成:

    new SkillViewModel(){
        Name = 'e';
    }

当然可以在List对象而不是数组中创建类似的结构,但是我认为您可以理解上下文是在SkillViewModel之外确定的,不再需要作为内部的属性。< / p>


另一种方法与我在第一句中写的一样,但有更多细节:您可以添加属性position

    new SkillViewModel()
    {
        Name = "e",
        Position = 1,
        Weight = 1
    }

像这样的PositionWeight与代码中的物理位置分离,并且可以获得与另一个对象相同的值。

编辑:
也许您已经忘记了想法,即元素的排序是如此重要且至关重要。为每个对象分配所需/所需的值,并根据权重或位置对其进行排序,您可以使用不同的方法来排序和创建view