PDA

View Full Version : الگوریتم برنامه شمارش داده های تکراری



hamed1376
شنبه 09 بهمن 1395, 18:11 عصر
سلام
من یه سری داده دارم که میخوام از این داده ها تکرار ها رو بر اساس ID شمارش و سپس تکرار ها رو حذف کنم یه توضیح با جدول در زیر میدم

داده های من


COUNT ----------------------- ID
--------------------------------------

4858--------------------0
4020------------------0
4858----------------------0
4858----------------------0
1020----------------------0
4020-----------------------0
1020-----------------0


بعد از مرتب سازی

COUNT ---------------------- ID
--------------------------------------

4858--------------------3
4020-------------------2
1020----------------------2

این کد رو نوشتم ولی درست کار نمیکنه ممنون میشم راهنمایی کنید



for (int data_i = 0; data_i < data.length(); data_i++) {
StructorRecords records = new StructorRecords();
JSONObject data_obj = data.getJSONObject(data_i);

records.recorusername = data_obj.getString(TAG_USERNAME);
records.id = data_obj.getString(TAG_ID);
records.full_name = data_obj.getString(TAG_FULL_NAME);
records.recordimg = data_obj.getString(TAG_PROFILE_PICTURE);
records.count = 1;


if (onelike==true){
G.savelike.add(records);
onelike=false;
}else {
for (int j = 0; j < G.savelike.size(); j++) {
StructorRecords Record = G.savelike.get(j);
if (Record.id == records.id) {
Record.count = Record.count++;
break;
} else {

G.savelike.add(records);
break;
}
}
}

vahid-p
شنبه 09 بهمن 1395, 20:35 عصر
متد sortAndCount در ورودی آرایه نامرتب ids رو میگیره و در خروجی یک آرایه دو بعدی که دو سطر داره (سطر اول برای آی دی ها و سطر دوم برای تعداد دفعات تکرارشون).
با مثالی که وجود داره، فکر میکنم عملکردش واضح باشه.

import java.util.Arrays;import java.util.LinkedList;
import java.util.Queue;


public class Test {
/**
* @param ids
* @return sorted 2D array - first row for ids and second row for counts
*/
public static int[][] sortAndCount(int[] ids) {
int lastElement, count;
Queue<Integer> sortedIds = new LinkedList<>();
Queue<Integer> sortedCounts = new LinkedList<>();


Arrays.parallelSort(ids);
lastElement = ids[0];
count = 1;


for (int i = 1; i < ids.length; i++) {
if (lastElement == ids[i]) {
count++;
} else {
sortedIds.add(lastElement);
sortedCounts.add(count);
lastElement = ids[i];
count = 1;
}
}
sortedIds.add(lastElement);
sortedCounts.add(count);

// Convert to 2D array & invert
int[][] outputArray=new int[2][sortedIds.size()];
for(int i=outputArray[0].length-1;i>=0;i--){
outputArray[0][i]=sortedIds.poll();
outputArray[1][i]=sortedCounts.poll();
}
return outputArray;
}

public static void main(String[] args) {
int[] ids=new int[]{4858,4020,4858,4858,1020,4020,1020};
int[][] sortedList = Test.sortAndCount(ids);
for(int i=0;i<sortedList[0].length;i++){
System.out.println(sortedList[0][i]+"--"+sortedList[1][i]);
}
}
}



خروجی:


4858--3
4020--2
1020--2

hamed1376
دوشنبه 11 بهمن 1395, 22:35 عصر
متد sortAndCount در ورودی آرایه نامرتب ids رو میگیره و در خروجی یک آرایه دو بعدی که دو سطر داره (سطر اول برای آی دی ها و سطر دوم برای تعداد دفعات تکرارشون).
با مثالی که وجود داره، فکر میکنم عملکردش واضح باشه.

import java.util.Arrays;import java.util.LinkedList;
import java.util.Queue;


public class Test {
/**
* @param ids
* @return sorted 2D array - first row for ids and second row for counts
*/
public static int[][] sortAndCount(int[] ids) {
int lastElement, count;
Queue<Integer> sortedIds = new LinkedList<>();
Queue<Integer> sortedCounts = new LinkedList<>();


Arrays.parallelSort(ids);
lastElement = ids[0];
count = 1;


for (int i = 1; i < ids.length; i++) {
if (lastElement == ids) {
count++;
} else {
sortedIds.add(lastElement);
sortedCounts.add(count);
lastElement = ids[i];
count = 1;
}
}
sortedIds.add(lastElement);
sortedCounts.add(count);

// Convert to 2D array & invert
int[][] outputArray=new int[2][sortedIds.size()];
for(int i=outputArray[0].length-1;i>=0;i--){
outputArray[0][i]=sortedIds.poll();
outputArray[1][i]=sortedCounts.poll();
}
return outputArray;
}

public static void main(String[] args) {
int[] ids=new int[]{4858,4020,4858,4858,1020,4020,1020};
int[][] sortedList = Test.sortAndCount(ids);
for(int i=0;i<sortedList[0].length;i++){
System.out.println(sortedList[0][i]+"--"+sortedList[1][i]);
}
}
}



خروجی:


4858--3
4020--2
1020--2


با سلام
در حقیقت بنده یه دونه arraylist دارم که چهار بعد داره که یک بعد ایدی و یک بعد ان نام فرد و یک بعد یه متن و بعد هم قراره بعدا پر بشه تعداد دفعاتی که اون شخص ایدیش تو اarraylist هست حالا میخوام یه کد باشه که این تعداد رو شمارش کنه خودم این کد زیر رو نوشتم میخوام این کدم اصلاح بشه اگه امکان داشته باشه


public class counter {
public static ArrayList<StructorRecords> staticslike = new ArrayList<StructorRecords>();
public static void orderbylike() {
for (int i = 0; i <= G.savelike.size(); i++) {
StructorRecords records = new StructorRecords();
StructorRecords Recordi = G.savelike.get(i);
Integer icount=1;
for (int j=i+1;j<=G.savelike.size();j++) {
StructorRecords Recordj = G.savelike.get(j);
Log.i("error1",""+icount+"===="+Recordi.id+"----"+Recordj.id);
if (Recordi.id==Recordj.id){
icount=icount++;
G.savelike.remove(j);
Log.i("error",""+icount+"===="+Recordi.id+"----"+Recordj.id);
}
}
records.recorusername = Recordi.recorusername;
records.id = Recordi.id;
records.full_name = Recordi.full_name;
records.recordimg = Recordi.recordimg;
records.count = icount;
staticslike.add(records);

}
for (int i=0;i<staticslike.size();i++) {
StructorRecords Recordj = staticslike.get(i);
Log.i("likeall",""+Recordj.id+"---count=="+Recordj.count);

}


}
}
کل داد ها تو G.[I]savelike هست

vahid-p
چهارشنبه 13 بهمن 1395, 04:16 صبح
هر چند توصیه میشه در یک حلقه روی ArrayList عملیات حذف و درج انجام ندید (خصوصا اگر از for مخصوص آرایه ها استفاده کنید error میدهد)
اما در این مثال چون با حذف یک عنصر، عنصر بعدی مد نظر شما شماره عنصر حذف شده فعلی را میگیرد، در نتیجه بعد از
G.savelike.remove(j);
یک واحد از j کم کنید.

همچنین icount=icount++; رو بنویسید icount++;

در کل میتونه خیلی بهتر از این نوشته بشه، ولی همین هم جواب میده.
موفق باشید

hamed1376
چهارشنبه 13 بهمن 1395, 14:10 عصر
هر چند توصیه میشه در یک حلقه روی ArrayList عملیات حذف و درج انجام ندید (خصوصا اگر از for مخصوص آرایه ها استفاده کنید error میدهد)
اما در این مثال چون با حذف یک عنصر، عنصر بعدی مد نظر شما شماره عنصر حذف شده فعلی را میگیرد، در نتیجه بعد از
G.savelike.remove(j);
یک واحد از j کم کنید.

همچنین icount=icount++; رو بنویسید icount++;

در کل میتونه خیلی بهتر از این نوشته بشه، ولی همین هم جواب میده.
موفق باشید

سلام بازم ممنون بابت پاسخ کاملی که دادید به نظرتون این کد بنده په جوری میشه نوشت که هم قابل فهم باشه هم ساده تر باشه
ممنون

vahid-p
شنبه 16 بهمن 1395, 11:28 صبح
سلام بازم ممنون بابت پاسخ کاملی که دادید به نظرتون این کد بنده په جوری میشه نوشت که هم قابل فهم باشه هم ساده تر باشه
ممنون
ساده ترش اونی هست که نوشتم و مرتب کنی و بشمری. یا از یک HashMap استفاده کنی که کار سرچ رو سریعتر میکنه. چون کاری که میخوای انجام بدی برای تعداد زیاد مرتبه زمانیش زیاد میشه. کد شما از مرتبه O(n^2) هست. همچنین سعی کن بیشتر از توابع استفاده کنی و همه کارها رو تو یه تابع انجام ندی. مثلا اینجا مرتب سازی و شمارش رو میشه تو یه تابع جداگونه انجام داد و ادامش در تابع اصلی ...
یه سری نکات نگارشی هم در خوندن کد موثره. گفتن همش یکم طولانیه ولی مثلا سعی کن از عبارات با معنی یا عبارات ساده تر استفاده کنید. مثلا Recordi و Recordj خیلی جالب نیست. به نظر من یا ببین معنی داره، از اون استفاده کن تا زیاد شبیه هم نباشن. یا حتی میتونی i و j رو به عنوان اشاره گر استفاده کنی و...

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