C ++:删除矩阵中重复的数字

时间:2015-09-02 13:57:43

标签: c++ coordinates

我想从矩阵中删除数字,该矩阵表示格式为' x y z'的坐标。一个例子:

1.211 1.647 1.041

2.144 2.684 1.548

1.657 2.245 1.021

1.657 0.984 2.347

2.154 0.347 2.472

1.211 1.647 1.041

在这个例子中,坐标1和6是相同的(x,y和z是相同的),我想删除它们,但我不想删除只有一个值等于坐标3和4的x的情况-坐标)。

这些值在文本文件中,我想在另一个文件中甚至在同一个文件中打印没有重复的坐标。

3 个答案:

答案 0 :(得分:1)

一个非常简单的解决方案是将每一行视为一个字符串并使用一组字符串。当您逐行遍历文件时,检查集合中是否存在当前行,如果不存在,则插入并打印它。 复杂性:O(nlogn),需要额外的内存:在最坏的情况下几乎与输入文件相同

与先前的解决方案具有相同的复杂性和最坏情况下的内存消耗,您可以将文件加载到内存中,按行排序,然后在打印时轻松跳过重复项。如果允许你重新订购它,可以在文件内部完成相同的操作,这样你只需要很少的额外内存,但速度要慢得多。

如果内存和存储是一个问题(我假设你不能复制文件),你可以使用简单的方法比较当前行与打印前的所有前一行,用O(n ^ 2)复杂但没有额外的记忆。然而,这是一个相当糟糕的解决方案,因为您必须从文件中多次读取,与主存储器相比,这可能非常慢。

答案 1 :(得分:1)

如果您想保留订单,请如何执行此操作。

  1. 将坐标读入像这样的结构数组

    struct Coord
    { 
      double x,y,z; 
      int pos;
      bool deleted;
    };
    

    pos是行号,删除设置为false。

  2. 对任何轴倾向于显示最大变化的结构进行排序。

  3. 运行数组,比较您在前一项的排序中使用的轴的值与当前项中的值。如果差异小于某个预设增量(.ie如果你关心小数点后面的三位数,你会寻找差异0.000999999左右)你比较剩余的值并设置删除任何行x,y, z足够接近。

    for(int i=1;i<count;i++)
    {
      if(fabs(arr[i].x-arr[i-1].x)<0.001)
        if(fabs(arr[i].y-arr[i-1].y)<0.001)
          if(fabs(arr[i].z-arr[i-1].z)<0.001)
            arr[i].deleted=true;
    }
    
  4. 再次对数组进行排序,这次按pos递增以恢复顺序。

  5. 浏览数组并输出deleted为false的所有项目。

答案 2 :(得分:0)

在c ++中,您可以使用STL的强大功能来解决这个问题。使用map并将三个坐标x,y和z存储为地图中的关键字。键的映射值将存储该键的计数。

Key_type = pair<pair<float,float>,float>
mapped_type = int

使用上面给出的key_type和mapped_type创建一个map m,并将所有行插入到map中,更新每行的计数。我们假设n是总行数。

for(i = 0; i < n; i++) {
        m[make_pair(make_pair(x,y),z)]++;
}

每次插入都需要O(logn),你必须插入n次。因此,总体时间复杂度将为O(nlogn)。现在,再次循环遍历矩阵的所有行,如果该行的mapped_value为1,则它是唯一的。