سوال: حذف خروجی تکراری در برنامه c++ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

سوال: حذف خروجی تکراری در برنامه c++

+1 امتیاز

سلام
من یه برنامه دارم مینویسم که هر بار خروجی زیر رو (اعداد مثال هستند) تولید میکنه. در واقع 8 تا عضوه که هر کدوم داره سطر و ستون ماتریس رو نشون میده.اما چون باید خروجی تولید شده در هر بار اجرا تکراری نباشه نمیدونم چی کار کنم که نتایج تکراری دوباره تو خروجی نمایش داده نشن. یعنی میخوام یه جوری همه ی خروجی ها از اول یه جا ذخیره بشن و هر خروجی با قبلیا مقایسه بشه و اگه تکراری بود دوباره نمایش داده نشه. البته شرط تکراری بودن اینه که اگه هر ۸ تا عضو با هر ۸ تای دیگه یکی بود نمایش داده نشه ولی اگه حداقل تو یکی از عضوها اختلاف داشتن اشکال نداره. لطف کنید راهنمایی کنید چطوری پیاده سازی کنم ممنون میشم. 

 

  1. [0],[4]
  2. [1],[4]
  3. [2],[3]
  4. [3],[5]
  5. [4],[7]
  6. [5],[1]
  7. [6],[5]
  8. [7],[2]
سوال شده فروردین 19, 1393  بوسیله ی cyber (امتیاز 38)   4 8 11
دوباره نشان داده شد فروردین 19, 1393 بوسیله ی BlueBlade

2 پاسخ

+2 امتیاز
 
بهترین پاسخ

یکی از ویژگی های std::set اینه که زمان اضافه کردن عنصر جدید تکراری بودن چک میشه

در مورد سوال شما نیاز به  یک custom function  برای چک کردن تکراری بودن هم دارید

به این شکل :

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>


struct CustomCompare
{
    bool operator()(const std::vector< std::pair<int,int> >& a ,
                    const std::vector< std::pair<int,int> >& b)
    {
        if(a.size() != b.size())
            return true;
        for(int i=0;i<a.size();i++)
        {
            bool flag =true;
            for(int j=0;j<b.size();j++)
            {
                if(a[i].first==b[j].first && a[i].second==b[j].second)
                {
                    flag=false;
                    break;
                }
            }
            if(flag)
                return true;
        }
        return false;
    }
};

int main()
{
    std::set< std::vector< std::pair<int,int> > ,CustomCompare >  vec;


    //por kardan
    std::vector<std::pair<int,int>> part1={ {1,2}, {2,5} , {3,9} };
    std::vector<std::pair<int,int>> part2={ {2,5} ,{1,2}, {3,9} };
    vec.emplace(part1);
    vec.emplace(part2);

    //neshan dadan list bedoon tekrari
    for (auto it=vec.begin(); it!=vec.end(); ++it)
    {
        const std::vector<std::pair<int,int>>& item = *it;
        for(int i=0;i<item.size();i++)
        {
            std::cout<<item[i].first<<"  "<<item[i].second<<'\n';
        }
    }
}

 

پاسخ داده شده فروردین 19, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد شهریور 5, 1393 بوسیله ی BlueBlade
خیلی ممنون مشکل حل شد..
اگه مشکلت رو حل کرد چرا پاسخش رو انتخاب نمیکنی تا پرسشی که کردی جوابش معلوم بشه ؟ و اگه یکی دیگه بیاد همچین مشکلی داشته باشه کارش سریع تر را بیفته . نه اینکه تا مشکلت حل شد همین طوری بزاری بری !
من تازه اومدم تو این انجمن نمیدونستم. فکر کنم منظورتون نشانه گذاری بود که انجام دادم الان. ممنون.
نه منظورم اون تیکی که برای انتخاب پاسخ هست رو بزن . همین پاسخی که نشانه گذاری کردی بالاش یه تیک داره .
+2 امتیاز

برای تولید اعداد تصادفی میتونید از ()rand و ()srand استفاده کنید .

و اعداد تولید شده رو در هر بار داخل یک فایل ذخیره کن .

و هر باری کی برنامه اجرا میشه . اعداد تولید شده جدید رو با اعداد ذخیره شده در فایل مقایسه کن . اگه اونطوری که میخوای نبود اعداد رو دوباره تولید کن . و وقتی که به اعداد مورد نظر رسیدی اونها رو به جای اعداد قدیمی ذخیره کن تا با دوباره اجرا شدن برنامه اعداد تکرار نشن .

 

UPDATE :

 

ببین نسبت به دیدگاه هایی که گذاشته شد . من میتونیم یه چیزی شبیه به اون چیزی که میخوای رو بنویسم .

اینو نگاه کن :

ٰٰ#include <iostream>
#include <map>
#include <utility>
using namespace std;

const int MOD_ADLER = 65521;
 
uint32_t adler32(unsigned char *data, int32_t len) /*  where data is the location of the data in physical memory and 
					                                len is the length of the data in bytes */
{	
   uint32_t a = 1, b = 0;
   int32_t index;
		 
   /*  Process each byte of the data in order */
   for (index = 0; index < len; ++index)
   {
      a = (a + data[index]) % MOD_ADLER;
      b = (b + a) % MOD_ADLER;
   }
																  
   return (b << 16) | a;
}

struct entry
{
	struct index_pair
	{
		size_t x,y;
	};

	index_pair indices[8];
};


entry make_entry (void)
{
	entry s;
	// tolid kardane 8 ta joft index mesle [2][3] 
	return s;
}

int main ()
{
	const int MAX = 30;
	int CUR = 0;

	map<uint32_t,entry> data;
	entry e = make_entry ();
	uint32_t checksum = adler32(reinterpret_cast<unsigned char*>(&e),sizeof(entry));

	auto ret =	data.insert( std::pair<uint32_t,entry>(checksum,e));
	if(ret.second == true) CUR++;

	return 0;
}

این کد رو باید خودت تغییر بدی . مثلا باید داخل یک حلقه بزاری و تمام entry ها رو به map بدی تا اینکه CUR به عدد 30 برسه .

در واقع اون شرط آخری چک میکنه که entry داده شده تکراری هست یا نه . اگر نبود یکی به CUR اضاقه میکنه .

و وقتی که CUR تعدادش به ۳۰ تا برسه شما همه ی entry ها رو داخل map دارید و میتونی هر کاری باهاشون بکنی .

ساختار entry هم همون چیزیه که باید ۳۰ تا نمونه منحصر بفرد ازش بدست بیاد و ۳ تا از نمونش رو خودت توی دیدگاه گذاشتی .

از تابع Adler32  هم برای درست کردن checksum استفاده کردم .

تابع make_entry رو خودت باید پیاده سازی کنی که چطور میخوای این اعداد رو درست کنی و یک entry رو بسازی .

ساختار index_pair هم که برای نگهداری جفت اعدادی هست که هر باز هست تا از اون تولید میشه و داخل entry قرار میگیره .

 

پاسخ داده شده فروردین 19, 1393 بوسیله ی Ali Rahbar (امتیاز 4,240)   6 16 46
آخه اعداد خودشون بر اساس محاسبه تولید میشن و رندوم نیست. من فقط میخوام بدونم چطوری باید همه ماتریس ها رو ذخیره کنم و چطوری باید با هم مقایسه کنم؟
ماتریس هات 1x2 هستن ؟
هر جور که هستن . میتونی با یک تابع checksum مثلا Adler-32 برای هر کدوم checksum بدست بیاری و checksum ها رو با هم مقایسه کنی .
Adler-32 برای هر جور داده یک مقدار 32 بیت برمیگردونه .
هم توضیح و هم کدش اینجا هست :‌http://en.wikipedia.org/wiki/Adler-32
برای کار کردن با فایل هم اینجا خیلی خوب توضیح داده شده :
http://www.7khatcode.com/33/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%DA%A9%D8%A7%D8%B1-%D8%A8%D8%A7-%D9%81%D8%A7%DB%8C%D9%84-%D8%AF%D8%B1-c
ببینید یه ماتریس 8*8 هستش که 8 تا گزینه که اول نوشتم هر کدوم به یه خونه ی ماتریس اشاره میکنن. و با هر بار اجرا هر 8 تا گزینه تولید میشه و میشه یه مجموعه ی 8 تایی که همون طور که گفتم هر کدوم از 8 تا به یه سطر و ستون ماتریس اشاره میکنن. حالا من میخوام 30 تا خروجی بگیرم ولی میخوام هیچ کدوم از خروجی ها دقیقا مثل هم نباشن. پس احتمالا باید همه خروجی ها رو یه جا ذخیره کنم و خروجی بعدی رو با قبلیا مقایسه کنم که اگر یکی بود نمایش نده. ولی نمیدونم چه طوری باید همه رو یه جا ذخیره کنم و بعد چجوری مقایسه کنم؟ اگه راه حلش checksum هست چطوری پیاده سازی کنم؟ اگه میشه یه کد بهم بدید از اون لینکه چیز زیادی متوجه نشدم.
شما الان مشکلت ذخیره کردن یک ماتریس در فایله ؟
نه من مشکلم ذخیره کردن ماتریس نیست. من مشکلم اینه که برنامه من فقط ۳۰ تا خروجی منحصر به فرد داره اما چون خروجی های تکراری هم نمایش داده میشن بالای ۲۰۰ تا خروجی نمایش داده میشه. که خیلی ها تکراری هستن. من میخوام با یه روشی اون خروجی های تکراری رو حذف کنم و فقط ۳۰ تای اصلی رو نمایش بده. همون طور که گفتم یه ماتریس ۸*۸ هست که با هر بار اجرا گرفتن ۸ تا خونه ی مختلف از ماتریس نمایش داده میشه. و در آخر یه خروجی ۳۰ تایی منحصر به فرد تولید میشه که مثلا من ۳ تاشو در زیر نوشتم:

1:
1:[0],[5]
2:[1],[3]
3:[2],[0]
4:[3],[4]
5:[4],[7]
6:[5],[1]
7:[6],[6]
8:[7],[2]


2:
1:[0],[6]
2:[1],[1]
3:[2],[3]
4:[3],[0]
5:[4],[7]
6:[5],[4]
7:[6],[2]
8:[7],[5]


3:
1:[0],[7]
2:[1],[3]
3:[2],[0]
4:[3],[2]
5:[4],[5]
6:[5],[1]
7:[6],[6]
8:[7],[4]
.
.
.
آهان .  یعنی می خوای تمام این  ماتریس ها رو ذخیره کنی بعد تکراری هاش رو حذف کنی درسته ؟
بله دقیقا. یعنی ۳۰ تا خروجی بدون تکرار داشته باشم.
کد بالا رو تغییر دادم . یه نگاه بکن بهش ...
...