首页 > 解决方案 > 如何在 2 个数组之间打印不常见的值?

问题描述

我想比较存储在文件名[i]和文件名[j]中的值,并打印出文件名[i]中与文件名[j]中文件名不同的值。我知道可以使用 set_difference 和 sort 解决方案,但我不确切知道要编写 sort 和 set_differences 代码。在这里,我提供了我的原始代码,以便您可以对其进行测试并更多地了解我正在尝试做什么。

我的完整代码:

#include <string>
#include <iostream>
#include <ctime> //important when to make random filename- srand(time(0))
#include <opencv2\opencv.hpp> //important when using opencv
#include <vector>   //when using vector function

using namespace std;
using namespace cv; //important when using opencv

int main(int argc, char* argv[]) {

vector<String> filenames;
int a, i;
srand(time(0)); //seed random filenames - for random filename


// Get all jpg in the folder

cv::glob("C:\\Users\\x\\Documents\\Aggressive\\abc", filenames);

for (size_t i = 0; i < filenames.size(); i++)
{
    Mat im = imread(filenames[i]); //read the filename location


   std::cout << "\n";

    std::size_t found = filenames[i].find_last_of("//\\");
    //std:cout << " file: " << filenames[j].substr(found + 1) << '\n'; //display filename and its format (.jpg)

    std::string::size_type const p(filenames[i].substr(found + 1).find_last_of('.')); //eg: 2.jpg then it will find the last '.'
    std::string file_without_extension = filenames[i].substr(found + 1).substr(0, p); //eg: 2
    std::cout << " file : " << filenames[i].substr(found + 1).substr(0, p); //display filename without .jpg



}

cout << "\n";
cout << "There's " << filenames.size() << " files in the current directory.\n" << endl; // total file in the specific directory

cout << "Enter array size: \n";
cin >> a;

for (int j = 0; j < filenames.size(); j++) {
    //generate random filename
    int index = rand() % filenames.size(); //random based on total of the file in the directory
    //cout << filenames[index] << endl; //display the random number but might be redundant

    //swap filenames[j] with filenames[index]
    string temp = filenames[j];
    filenames[j] = filenames[index];
    filenames[index] = temp;
}

for (int j = 0; j < a; j++) {

    //cout << "Random image selected:" << filenames[j] << endl; //basically to avoid the redundant random filename

    Mat im = imread(filenames[j]); //read filename location

    std::size_t found = filenames[j].find_last_of("//\\");
    //std:cout << " file: " << filenames[j].substr(found + 1) << '\n'; //display filename and its format (.jpg)

    std::string::size_type const p(filenames[j].substr(found + 1).find_last_of('.')); //eg: 2.jpg then it will find the last '.' 
    std::string file_without_extension = filenames[j].substr(found + 1).substr(0, p); //eg: 2
    std::cout << " file: " << filenames[j].substr(found + 1).substr(0, p); //display filename without .jpg

    string written_directory = "C:/Users/x/Documents/folder/" + filenames[j].substr(found + 1).substr(0, p) + ".jpg"; // write filename based on its original filename.
    imwrite(written_directory, im);

}


return 0;
}

标签: c++arrayssortingset-difference

解决方案


在我看来,这是一个XY Problem的完美例子。从你的问题,从你的代码,甚至从评论来看,人们并不真正理解你想要做什么。我的意思是,你想达到什么目标?

您想将指定数量的随机选择的 JPEG 文件从一个目录复制到另一个目录,这是一个模糊的猜测。并且您要显示不会被复制的文件的文件名。

让我举几个例子,这一切混乱的原因是什么。

首先也是最重要的,您没有显示完整的代码。缺少定义和变量类型和函数。这也不是一个最小的、可重现的示例。而且您问题中的描述很难理解。

我有两组数组

你有“两套阵列”吗?你的意思是,你有 2[std::set][3][std::array][3]。或者,也许您只有 2[std::vector][3]std::string。从我们在代码中可以看到,我们可以假设 a std::vector<std::string>>,但我们不知道,因为您没有显示“文件名”的伪装。

然后,你在谈论“2”的东西。但我们确实只看到一个“文件名”。那么,2还是1?

在你正在写的评论中

在数组 2 中,我有一个基于用户输入的数组大小的随机文件名

我的猜测是你不想有一个随机的文件名,但你想从第一个向量中选择具有随机索引的文件名并将其放入第二个向量中?但是我们只能看到 1 个向量“文件名”,您可以在其中进行一些随机交换活动。

然后你写了

imread 实际上是读取目录文件夹中的整个文件

这个功能很重要,它有什么作用?“读取文件”是什么意思?你的意思是“文件名”,所以文件名?还是文件的内容?“目录的文件夹”是什么意思?一个文件夹中的所有文件名?还是目录条目的子文件夹?

所以现在我的目标是打印出数组 2 中所有文件名不同的文件

同样,我们真的有 2 个数组(向量)吗?他们有什么不同吗?

然后,您将文件复制到哪里?


所以,你看,这很难理解。即使人们愿意帮助你,他们也不能,因为他们不了解你。最好显示指向您原始家庭作业的链接。然后人们可以帮助你。Stack Overflow 上的成员希望提供帮助。但请允许他们这样做。

这里我给你一个随机选择问题和set_difference问题的抽象例子:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <random>

int main() {
    // Define 2 Vectors for filenames

    // This vector is an example for files that could be in a specified directory
    std::vector<std::string> fileNamesInDirectory{"8.jpg","5.jpg", "6.jpg", "9.jpg", "1.jpg", "4.jpg", "2.jpg", "3.jpg", };

    // Print the filenames as information for the user
    for (size_t i = 0U; i < fileNamesInDirectory.size(); ++i) {
        std::cout << fileNamesInDirectory[i] << "\n";
    }

    // Next: Select randomly a given number of filenames from the above vector

    // So, first get the number of selections. Inform the user
    std::cout << "\nEnter a number of filenames that should be copied randomly. Range: 1-"<< fileNamesInDirectory.size()-1 << "\t";
    size_t numberOfSelectedFileNames{};
    std::cin >> numberOfSelectedFileNames;

    // Check for valid range
    if (numberOfSelectedFileNames == 0 || numberOfSelectedFileNames >= fileNamesInDirectory.size()) {
        std::cerr << "\n*** Error. Wrong input '" << numberOfSelectedFileNames << "'\n";
    }
    else {
        // Copy all data from fileNamesInDirectory
        std::vector<std::string> selection{ fileNamesInDirectory };

        // Shuffle the data randomly: Please see here: https://en.cppreference.com/w/cpp/algorithm/random_shuffle
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(selection.begin(), selection.end(), g);

        // Resize to the number, given by the user
        selection.resize(numberOfSelectedFileNames);

        // Now we have a random list of filenames
        // Show, what we have so far. Now, because we are learning, we will use the range based for
        std::cout << "\n\nOriginal file names:\n";
        for (const std::string& s : fileNamesInDirectory) std::cout << s << "\n";
        std::cout << "\n\nRandomly selected file names:\n";
        for (const std::string& s : selection) std::cout << s << "\n";

        // Sort both vectors
        std::sort(fileNamesInDirectory.begin(), fileNamesInDirectory.end());
        std::sort(selection.begin(), selection.end());

        // Show again to the user:3

        std::cout << "\n\nOriginal file names sorted:\n";
        for (const std::string& s : fileNamesInDirectory) std::cout << s << "\n";
        std::cout << "\n\nRandomly selected file names sorted:\n";
        for (const std::string& s : selection) std::cout << s << "\n";

        // Now, find out the difference of both vectors, meaning, what will not be selected and later copied
        std::vector<std::string> difference{};

        // Calculate the difference with a std::algorithm: https://en.cppreference.com/w/cpp/algorithm/set_difference
        std::set_difference(fileNamesInDirectory.begin(), fileNamesInDirectory.end(), selection.begin(), selection.end(), std::back_inserter(difference));

        std::cout << "\n\nThe following file names have not been selected:\n";
        for (const std::string& s : difference) std::cout << s << "\n";

    }
    return 0;
}

如果您更高级,那么您可以并且将使用 C++文件系统库中的函数。这将使生活更轻松。. .


推荐阅读