PDA

View Full Version : سوال: سورس پیدا کردن خطوط و کلمات تکراری (بهترین الگوریتم)



mahdishahidi
دوشنبه 03 اسفند 1394, 18:15 عصر
سلام دوستان یک فایل حدودا 5گیگابایتی دارم که که می خوام کلمات تکراری توی اون حذف بشن و برای این کار سریعترین الگوریتم رو می خوام
مثال:
ورودی:
59548
63182
63612
25079
62977
25076
25624
62977
36447
94214
25079
62977

خروجی:
25076
25079
25624
36447
59548
62977
63182
63612
94214

(textbox)

pbm_soy
دوشنبه 03 اسفند 1394, 19:43 عصر
بهتر بود میگفتید هدفتون چیست؟ ویا بیشتر شرح میدادید؟
آیا فایل مرتب است؟ احتمالا جواب منفی است
ولی اگر فایل را یکبار در آرایه میخواندید و مرتب میکرید و بعداز روشهای سریعتری را میتوانستید پیاده کنید که تکرار نباشه و یا داده ها را بدون تکراری در فایل جدید بنویسید
ولی وقتی قرار است فایل را بخوانید و در آارایه بریزید پس بهتر در همان لحظه هم بررسی کنید که تکرار نباشد و اگر در آارایه نبود در آنصورت بریزد در آرایه و آخر سر آرایه را در فایل جدید بنویسید
حالا همان کار بالا را درنظر بگیرید ولی بجای ریختن در آارایه در یک درخت دودویی را درنظر بگیرید درخت جستجوی دودویی binnary search tree
در این درخت داده تکرار وارد نمیشود و جستجو در آن سریع است کوتاه میگم اولین داده در ریسشه درخت قرار داده میشود و داده بعدی که از فایل میخوانید اگر از ریشه بزرگتر باشد به عنوان فرزند سمت راست در درخت ثبت میشود و اگر کوچکتر باشد سمت چپ و داده بعدی نیز به همین ترتیب با ریشه مقایسه میشود و اگر بزرگتر باشد با فرزند سمت راست مقایسه میشود و باز اگر از فرزند سمت راست بزرگتر باشد دوباره با فرزند سمت راست آن گره نیز مقایسه میکند اینکار تازمانی تکرار میشود که یا در یکی از این گره ها داده موجود با داده خوانده شده از فایل برابر باشد و یا اینکه دیگر گره مورد نظر فرزندی نداشته باشد که در اینصورت به عنوان فرزند سمت راست یا چپ درج میشود
خاصیت این نوع درخت هرگز داده تکراری ثبت نمیشود و زمانهای جستجو نیز سریعتر است و در آخر کار کل درخت را در فایل جدید بنویسید

چون منظور شما از سریعترین مشخص نبود بد نیست موارد زیر را هم بگم
در زمان خواند فایل بجای ریختن در آرایه میتوانید در یک hash table و یا dictionary که جزو ساختمان داده های خوب و پیشرفته و سرعت بالای c# هستند بریزید خاصیت این ساختمان داده ها اینه که داده تکراری نمیپذیرند شما خیلی راحت داده خوانده شده را به دیکشنری یا به جدول هش اضافه کنید اگر تکراری بود قبول نمیکنند یکی exception تولید و دیگری null برمیگرداند فقط آنرا باید صحیح کدنویسی کنید
دقت کنید دیکشنری سریعتر از جدول هش است
و آخر کار همه را در فایل جدید بنویسید

pbm_soy
دوشنبه 03 اسفند 1394, 19:47 عصر
یادم رفته بود ذکر کنم
اگر قرار باشد از امکانات زبان برنامه نویسی استفاده کنیم در سی شارپ array , arraylist , list یا حتی آرایه معمولی امکان حذف تکراری را با یک متد میدهند به عنوان مثال به کد زیر توجه کنید



int[] nums = {1, 1, 2, 3, 4, 4};
int[] unique = nums.Distinct().ToArray();


ویا به کد زیر توجه کنید


int[] nums = { 1, 1, 2, 3, 4, 4 };
List<int> unique = new List<int>();
foreach (int n in nums)
if (!unique.Contains(n))
unique.Add(n);

mahdishahidi
سه شنبه 04 اسفند 1394, 08:32 صبح
سپاس بابت پاسخ
خیر مرتب شده نیست
این روش که شما گفتی مطمئن هستید که سریعترین هست؟ و مهم تر اینکه برنامه کرش نمیشه؟
میشه روی این کدی که دادین کمی بیشتر توضیح بدین؟
الان یکی از مشکلات ایجاست که طوری متن از توی textbox بیارم توی ارایه. در وافع با #C چه طوری میشه خطوط رو تشخیص داد؟

pbm_soy
سه شنبه 04 اسفند 1394, 14:54 عصر
روش استفاده از درخت جستجوی دودویی جزو سریعترین روشها برای حزو تکراریها و جستجو کردن است هرچند که شاید روشهای سریعتر دیگری هم باشد ولی فکر نمیکنم خیلی سریعتر از این باشد باید دقیقتر بگردم تا جواب دقیقتر بگم
در مورد کرش کردن و سریعتر شدن برنامه هم به روش پیاده سازی و کدنویسی شما بستگی دارد مثلا شما برنامه را همینجوری خطی بنویسید شاید کند بشه و یا نتیجه را مستقیم در فرم بخواهید نمایش دهید مسلما کند میشود
اگر حجم داده ها زیاد است بهتر است برنامه را چندنخی بنویسید که مشکل کرش کردن و کندی را تا حدودی میتوانید برطرف کنید

مورد بعدی فکر میکنم روشها ومتدهای c# به اندازه کافی بهینه باشد و فکر نمیکنم نیازی باشد که خودتون اوریتم را از پایه پیاده سازی کنید
و همین کدهایی که گفتم کارت را راه میاندازد و یا از دیکشنری استفاده کنید باز هم نتیجه مناسب میگیرید

pbm_soy
سه شنبه 04 اسفند 1394, 15:05 عصر
طبق گفته شما تو تکست باکس این همه متن هست؟! برای نمایش دادن در فرم کار جالبی نیست بهتر است متن را تیکه تیکه در فرم نمایش دهید
درهرصورت برای خواندن متن از تکست باکس راههای زیادی وجود دارد راه ساده




String [] allwords=textbox.text.split(" ");


چدستور بالا آارایه متنی میسازد و متن موجود در تکست باکس را از محل فضای خالی جدا میکند یعنی کلمه به کلمه جدا میکند و هرکدام را در خانه های آرایه قرار میدهد
اگر متن در فایل هم باشد قبل از دستور بالا فایل را بازکنید و کل محتوای را بصورت رشته ای در متغییر رشته ای ذخیره کنید حالا متغییر رشته ای هم متد split دارد که متن کلمه به کلمه جدا میکند
البته کارهای دیگه هم میتوانید بکنید textbox1.text.substr اجازه دستزسی به تک تک کاراکترهای موجود در متن را میدهدو یا اینکه textbox1.text[i] یک آرایه فقط خواندنی است و میتوانید به تک تک کاراکترها دسترسی دارید ویا اگر multiline باشد خصوصیت lines یک آرایه است و جازه دسترسی به تک تک خطوط موجود در تکست باکس را میدهد

pbm_soy
سه شنبه 04 اسفند 1394, 15:15 عصر
در مورد کدهای نوشته شده در پست بالا باید بگم کد اولی آرایه ای بنتام num تعریف میکند و در آن داده هاینمونه میریزد و در سطر دوم از روی آرایه اول یک کپی در آرایه unique درست میکند ولی داده ها را که کپی میکند بصورت منحصربفرد است یعنی داده های تکراری را حذف میکند
متد dirinct تکراریها را حذف میکند و toarray نتیجه را بصورت آرایه شده برمیگرداند و در unique ذخیره میکند
کد دوم
در سطر اول آرایه num ایجاد شده و داده میریزد و سطر دوم آرایه ای از نوع لیست ایجاد میکند و سپس یک حلقه به تعداد اعناصر num ایجاد میکند و
دستور شرط میگوید اگر unique مقدار n را نداشته باشد
دستور داخل شرط میگوید unique مقدار n را اضافه کن
در کل تک تک مقادیر num به داخل unique اضافه شود فقط درصورتی که مقدار num در unique وجود نداشته باشد اضافه شود

mahdishahidi
سه شنبه 04 اسفند 1394, 17:47 عصر
مرسی فقط برای خواندن و نوشتن از یک آرایه (که عناصر تکراری رو حذف کردم ازش) از چه راه هایی باید استفاده کنم؟ (نوشتن توی textbox)
"چندنخی" رو اگه میشه یکم توضیح بدین

pbm_soy
سه شنبه 04 اسفند 1394, 18:46 عصر
منظورتون از سوال اول را نفهمیدم!
در مورد برنامه نویسی چند نخی هم مطلب تو این سایت زیاد است اول سرچ کنید
فقط کوتاه میگم برنامه نویسی چند نخی اینه که شما میتوانید چندین زیر برنامه یا تابع و پروسیجر برنامه را بصورت موازی اجرا کنید
همانطور که خودتون میدانید همیشه تابع اول اجرا میشود و پس اتمام تابع اول تابع دوم و یا دستورات بعدی اجرا میشود و پس اتمام اینها نوبت به تابع بعدی میرسد یعنی اجرای برنامه بصورت ترتیبی است ولی با چند نخی میتوانید بخشهایی از برنامه را بصورت موازی اجرا کنید
یکی از کاربردهاش اینه که برای اینکه برنامه قفل نکند مخصوصا در زمان کار با داده هایی با حجم بالا استفاده از این روش بهترین کار است!


من در اینجا خیلی کوتاه و بصورت ساده این قضیه را گفتم