比较同一列中的字符串

Compare strings in same column

本文关键字:一列 字符串 比较      更新时间:2023-10-16

我下载了一个图片数据库。

数据库附带一个CSV文件,该文件对每张图片进行编码,并识别图片中的重要像素。

第一列是主题的字符串代码,例如i000ra-fn000是实际代码,所有字符串都以i开头。3位数字后的字母表示不同的东西,如灯光、相机角度等。

因为主题000可以有很多张照片,由于光线和相机角度的不同,我想只保留1张。

所以我想做的是,检查第1列中以i000开头的图片的数量。然后随机保留其中一个,随后删除其余的,无论是在我的csv文件还是在我的硬盘驱动器上。

然后我将遍历列中的每个名称,直到我已经区分的主题的数量。

我是c++的新手,不知道怎么做这个。你能给我一些建议吗?到目前为止,我已经将csv文件加载到矢量的矢量中。跳过第一列并将其加载到名为names的单独向量中。我不知道如何继续下去……有什么建议吗?

int main(int argc, const char** argv)
{
    ifstream landmarksFile("muct76-opencv.csv");
    string row;
    string cell;
    vector<vector<double>> allLandmarks;
    vector<double> individualsLandmarks;
    vector<string> names;
    // skip headers
    getline(landmarksFile, row);
    // continue...
    while (getline(landmarksFile, row))
    {
        stringstream iss(row);
        while (getline(iss, cell, ','))
        {
            size_t found = cell.find("i");
            if (found != string::npos)
            {
                names.push_back(cell);
            }
            else
            {
                individualsLandmarks.push_back(atof(cell.c_str()));
            }
        }
        allLandmarks.push_back(individualsLandmarks);
        individualsLandmarks.clear();
    }
}

编辑:CSV文件样本…注意,列继续到x75、y75和

name        tag x00 y00 x01 y01 x02 y02 x03
i000qa-fn   0   201 348 201 381 202 408 209
i000ra-fn   0   187 326 184 358 182 390 186
i000sa-fn   0   190 344 191 385 197 414 206
i001qa-mn   0   162 368 165 399 172 421 178
i001ra-mn   0   166 370 171 404 178 430 185
i001sa-mn   0   166 369 173 404 177 429 185
i002qa-mn   0   224 289 224 323 223 347 227
i002ra-mn   0   221 288 221 323 222 348 229
i002sa-mn   0   222 302 227 329 230 349 239
i003qa-fn   0   182 429 182 456 187 478 196
i003ra-fn   0   178 429 180 458 184 478 193
i003sa-fn   0   180 432 181 461 185 481 193
i004qa-mn   0   182 258 187 289 185 312 190

可在此下载:https://code.google.com/p/muct/downloads/detail?name=muct-landmarks-v1.tar.gz&can=2&q=

  1. 所以我要做的是检查列1中以i000开头的图片的数量。然后随机保留其中一个,随后删除其余的,无论是在我的csv文件还是在我的硬盘驱动器上。

    首先,创建一个函数,从以i000开头的元素中创建一个向量。不太难…

    template<class Container, class UnaryOp>
    Container container_copy_if(const Container& c, UnaryOp pred)
    {
        Container temp;
        std::copy_if(std::begin(c), std::end(c), std::back_inserter(temp), pred);
        return temp;
    }
    ...
    auto vector_with_only_i000 = container_copy_if(names,
        [] (const std::string& name) {
             return name.substr("i000") != std::string::npos;
    });
    
  2. …然后随机保留其中一个,随后删除其余的,无论是在我的csv文件还是在我的硬盘驱动器上。

    必须使用随机数生成器。下面是如何使用std::uniform_int_distribution:

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dist(0, vector_with_only_i000.size() - 1);
    auto random_name = vector_with_only_i000.at(dist(rd()));
    

    现在你有了随机的名字,你可以从原始的names向量中删除所有不等于random_name的东西:

    auto not_equal_random_name = [&] (const std::string& name) {
        return name == random_name;
    };
    names.erase(
        std::remove_if(names.begin(), names.end(), not_equal_random_name),
        names.end());
    

    现在要从实际文件中删除它们,您需要这样做:

    1. 将文件中的每一行保存为矢量。
    2. 删除向量中不等于random_name的元素。
    3. 用新名称创建新文件
    4. 将矢量内容写入新文件
    5. 将文件重命名为旧的csv文件