【问题标题】:How to print uncommon value between 2 array?如何在 2 个数组之间打印不常见的值?
【发布时间】:2020-08-09 03:58:24
【问题描述】:

我想比较存储在 filename[i] 和 filename[j] 中的值,并打印出 filename[i] 中与 filename[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;
}

【问题讨论】:

  • 你有什么?你想得到什么?好像您有 2 个 std::string 数组。您想打印一个数组中的所有元素,而不是另一个。我不太明白您是否以及为什么要对其进行排序?你能告诉我我做对了什么吗?
  • 实际上,对于数组 1,它会显示一个文件夹中的所有文件名,而在数组 2 中,我有一个基于用户输入的数组大小的随机文件名。所以我现在的目标是我想打印出数组 2 中没有的所有文件名。这就是为什么我想对两个数组进行排序并设置这些数组之间的差异,以便我可以打印出不同的值文件名。
  • 标准库为您服务:std::set_difference.
  • @JesperJuhl 我已经尝试根据我的理解来编写代码,但似乎我犯了很多错误。所以可悲的是它对我不起作用。顺便说一句,我是编程的初学者,所以我不太了解它是如何工作的。
  • @WBuck 'array' 是什么意思足够小?以及如何使用二次方法?

标签: c++ arrays sorting set-difference


【解决方案1】:

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

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

让我给你一些例子,这一切混乱的原因是什么。

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

我有两组数组

你有“两套数组”吗?你的意思是,你有 2 个[std::set][3][std::array][3]。或者,您可能只有 2 个 [std::vector][3]std::string。从代码中我们可以看到,我们可以假设std::vector&lt;std::string&gt;&gt;,但我们不知道,因为您没有显示“文件名”的伪装。

那么,你在谈论“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++ filesystem library 中的函数。这将使生活更轻松。 . .

【讨论】:

  • 对不起,我的错误解释让您感到困惑。我已经更新了原始代码,以便您可以对其进行测试以更好地理解。如果有任何问题让您感到困惑,我会尽力解释。我已经坚持了好几天了,所以我希望你能帮助我。
猜你喜欢
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-15
  • 2015-05-25
  • 2017-08-03
相关资源
最近更新 更多