I have three arrays in my proggramme Surname, Forename and result and need to create a sort array
Surname: Chris Forename: Charleton: Result: 54
Surname: Annett: forename: Lyle: result 67
If I wanted to sort it by alphabetical of last name, i need all the fields to move, instead of just the surname. This is the bubble sort code i'm working off
int swap;
boolean swapflag = true;
//outer loop
while (swapflag == true)
{
swapflag = false;
//inner loop
for (int index=0; index < (nums.length - 1); index++)
{
//swap routine
if (nums[index]> nums[index + 1])
{ //swap routine
swap = nums[index];
nums[index] = nums[index + 1];
nums[index + 1] = swap;
swapflag = true;
}
}//end inner
}//end outer
System.out.println ("\nArray Contents after sorting"
+ "\n*************");
for (int index=0; index < nums.length; index ++)
{
System.out.println("Array element "
+ index + ": " + nums[index]);
}
}
}
` package projStudent;
import java.util.Scanner;
public class UnitResults
{
//delcare Scanner as keyb
static Scanner keyb = new Scanner (System.in);
//declare fields
static String studentForename [];
static String studentSurname [];
static int [] studentResult;
static int pointer;
//constructor
UnitResults(int sizeofclass)
{//start of constructor
studentForename = new String [sizeofclass];
studentSurname = new String [sizeofclass];
studentResult = new int [sizeofclass];
pointer = 0;
}//end of constructor
public boolean add(String studentForename[], String studentSurname[],
int studentResult[])
{//start of add method
if (pointer == studentResult.length )
{//start of if statement
System.out.println("Sorry Array is full");
return false;
studentResult[pointer] = studentResult[];
pointer ++;
}//end of if statement
}//end of add method
public boolean delete(int element)
{//start of delete method
element = element - 1;
if ((element >= 0) && ( element < pointer))
{//start of if statement
for(int index = (element + 1); index < pointer; index++)
{//start of for statement
studentResult[index - 1] = studentResult[index];
}//end of for statement
pointer--;
return true;
}//end of if statement
else
{//start of else statement
return false;
}//end of else statement
}//end of delete method
public String find()
{//start of display
String strOutput="";
strOutput = strOutput + "Students";
if (pointer==0)
{//start of if statement
strOutput = strOutput + "There are no records in this Array";
return strOutput;
}//end of if statement
for (int index=0; index < pointer; index++)
{//start of for method
strOutput = strOutput + "Student Name" + studentSurname[index] + studentForename +
"Student Result" + studentResult +"\n";
}//end of for method
return strOutput;
}//display
public int sort (int UnitResults)
{//start of sort
int sort;
boolean swapflag = true;
while (swapflag == true)
{//start of while loop
swapflag = false;
for (int index=0; index < (UnitResults - 1); index++)
{
if (studentResult[index]> studentResult[index + 1])
{ //swap routine
sort = studentResult[index];
studentResult[index] = studentResult[index + 1];
studentResult[index + 1] = sort;
swapflag = true;
}
}
}//end of while loop
}//end of sort
}`
Unfortunately, your post is confusing as you don't include some things, like just what is the current array you are sorting. Still, if I understand your question correctly...
Regardless of the language, your strategy would involve changes to how you swap the elements. If your array consists of composite data, then simply assigning in a swap is fine. If your data is scattered, then your swap needs to swap each variable. You can always just sort the indices of the array into another array, then use that array to indirectly reference the first, for sorted access.
I would suggest you use an List for this purpose.
First create an object. For example "Person" containing members for "Forname","Surename","Result". Then fill the list with these objects, implement the Interface Compareable and use the Collection.sort() methode.
class Person implements Comparable<Person>
{
private String forname;
private String surname;
private int rating;
public Person(String forename, String surname, int rating)
{
this.forname = forename;
this.surname = surname;
this.rating = rating
}
public int compareTo(Person p) {
if(p.rating == this.rating)
return 0;
else if(p.rating < this.rating)
return -1;
return 1;
}
}
class Test{
public static void main(String[] args){
List<Person> personList = new ArrayList<Person>();
Person p1 = new Person("John","Smith",10);
Person p2 = new Person("Max","Muster",20);
Person p3 = new Person("Sarah","Clark",15);
personList.add(p1);
personList.add(p2);
personList.add(p3);
personList.sort();
}
}
There are a number of features of the Java programming languages that can help you resolve the problem that you are having, the first of which is inclusion of appropriate data structures and methods with which to manipulate objects within those data structures.
First and foremost, I'd recommend using a java class to represent a single person entity... think about it, when you look up a person's information, you don't consult three separate books, or computer screens, or what have you, when all that information can be organized into one place. For your person above, for example, you could use something like this:
public class Person implements Comparable<Person> {
public String firstName;
public String lastName;
public int result;
public Person(String fn, String ln, int r) {
firstName = fn;
lastName = ln;
result = r;
}
public int compareTo(Person otherPerson) {
return lastName.compareTo(otherPerson.lastName);
}
}
This will give you an object that will store all of your person information, and by default will be easily sortable by last name (you can change this behavior with a comparator, which I won't cover here.)
Now instead of having three different arrays of first names, last names, and results, you can have a single array of Persons. There ARE actually sorting mechanisms within the java language for arrays already, which you can research and use if you choose, but if you'd like to use your own sort, you would just need to replace your swap conditional with something like this:
if(persons[index].compareTo(persons[index+1]) > 0) {
...
}
i just want ask you
why instead creating class student ie
class Student{
private String studentForename;
private String studentSurname;
private int studentResult;
//setters and getters
}
and put them in some collection ie List
you are putting them into 3 different arrays?
do you realize, if you have them nicely in the list, you can sort them just by using Collections.sort() ?
Can't understand properly the question: are you looking for a way to manually implement a sorting algorithm (bubble, quick or whatever) or you would like to simply sort them the best you can? Generally speaking you should never implement your own sort 'cause Java provides itself a very efficient lot... or is this an exercise? Probably :)
Best way I can imagine is, provided the 3 arrays in their original form are linked by index, create a surname/index map, load it form surname array, sort the Map.Entry by key and then you will have the array indexes sorted the way you wanted. Check here for more details: how to sort Map values by key in Java
PS The solutions provided by the others are correct and preferrable if you are NOT doing an exercise :) Better deal with a structured object than with 3 separated data.
Related
I have a class called Word in which each instance has String, ArrayList<Character>, and a double. Let's say there are 3 instances of this class. I would like to create a new ArrayList<String> in which all 3 word strings are contained. However, the order of the Strings must go from high to low of the doubles from their original instances. The major stipulation of this project is that the Collections.sort method cannot be used. Please see the code below and let me know if you can think of a way to write this loop (a loop is needed because there is actually +50,000 words):
import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
public class WordRecommender {
String fileName;
public WordRecommender(String fileName) {
this.fileName = fileName;
}
public static void main(String[] args) {
ArrayList<Word> objectArray = new ArrayList<Word>();
objectArray.add(new Word("people", null ,0.8));
objectArray.add(new Word("dogs", null ,0.4));
objectArray.add(new Word("cats", null ,0.6));
ArrayList<String> outputArray = new ArrayList<String>();
for (int i = 0; i < finalArray.size(); i++) {
// code here to find the value of each double and place the
// associated strings into output Array from highest to lowest
}
// ideal outputArray order = ["people", "cats", "dogs"]
}
import java.util.ArrayList;
public class Word {
String wordName;
ArrayList<Character> uniqueLetters;
double percent;
public Word(String string, double percent) {
ArrayList<Character> tempArray = new ArrayList<Character>();
for (int i = 0; i < string.length(); i++) {
tempArray.add(string.charAt(i));
}
this.wordName = string;
this.uniqueLetters = tempArray;
this.percent = percent;
}
}
The result you need to achieve can be broken in 2 major steps:
Describing how, giving 2 Words, which of them will be put before the other in the List
Using the comparing method to actually sort your list of Words.
Step 1: How can we decide which word comes first?
Java has an interface called Comparable. The name is pretty self-explanatory. When you implement this interface in your Word class, you are telling Java that instances of this class can be compared against each other.
public class Word implements Comparable<Word>{
When you edit this line in your Word class, your IDE will probably complain about a "missing compareTo() method". The compareTo() method is defined in the Comparable interface and its job is deciding, from 2 instances, which one should be considered "larger" (or in our case, should be put first in the List).
An example of a usage is: "apple".compareTo("banana");. This method call should return a positive number if the first instance ("apple") is "larger", a negative number if the second instance ("banana") is "larger", or zero if both are of the same "value". By the way, the compareTo() method implemented by Strings in Java evaluates instances by alphabetical order.
So let's implement our version of the compareTo() method for our Word class.
#Override
public int compareTo(Word anotherWord) {
if(this.percent > anotherWord.percent) {
return 1;
} else if (this.percent < anotherWord.percent) {
return -1;
} else {
return 0;
}
}
Keep in mind that this implementation returns a positive value if the first instance is greater than the second, and a negative value in the other way around.
Now that we have a way of comparing our Words, we can move on to the sorting part.
Step 2: Sorting algorithms
There are a huge variety of sorting algorithms available on the internet. Some are less efficient, some are easier to implement. You can research some of them here.
For me, the easiest sorting algorithm is called BubbleSort. It is not very efficient, though.
ArrayList<Word> objectArray = new ArrayList<Word>();
objectArray.add(new Word("people", 0.8));
objectArray.add(new Word("dogs", 0.4));
objectArray.add(new Word("cats", 0.6));
for(int i = 0; i < objectArray.size() - 1; i++) {
for(int j = 0; j < objectArray.size() - i - 1; j++) {
// Remember: a compareTo() call returning a negative number
// means that the first instance is smaller than the second.
if(objectArray.get(j).compareTo(objectArray.get(j + 1)) < 0) {
Word auxiliary = objectArray.get(j);
objectArray.set(j, objectArray.get(j + 1));
objectArray.set(j + 1, auxiliary);
}
}
}
These two nested for loops will sort objectArray in descending order of percent.
I implemented a solution that involves a sorting algorithm and usage of java.util.Comparable both.
First, you need to implement Word class with java.util.Comparable so that you can define how to compare Word class in order to determine which one is greater or lower than the other. In this case, it will be the percent field.
public class Word implements Comparable<Word> {
String wordName;
ArrayList<Character> uniqueLetters;
double percent;
public Word(String string, double percent) {
ArrayList<Character> tempArray = new ArrayList<Character>();
for (int i = 0; i < string.length(); i++) {
tempArray.add(string.charAt(i));
}
this.wordName = string;
this.uniqueLetters = tempArray;
this.percent = percent;
}
#Override
public int compareTo(Word o) {
// It is better to delegate to built-in Double compare
// because all we need to compare doubles
return Double.compare(this.percent, o.percent);
}
#Override
public String toString() {
return this.wordName;
}
}
Second, the most important part is to implement a sorting algorithm. It can be challenging to implement them on your own so I suggest study them first.
For my solution it will be a regular implementation of Quick Sort algorithm as follows:
public class QuickSort {
private Word[] array;
public QuickSort(Word... words) {
this.array = words;
}
public Word[] sort(){
this.sort(this.array, 0, this.array.length-1);
return this.array;
}
private void sort(Word[] array, int begin, int end) {
//exit condition
if (begin >= end)
return;
Word pivot = array[end];
int sortIndex = begin;
for (int i = begin; i < end; i++) {
// instead of > we use compareTo to externalize comparison logic
// greater than (>) means we sort in descending order
if (array[i].compareTo(pivot) > 0) {
Word swap = array[sortIndex];
array[sortIndex] = array[i];
array[i] = swap;
sortIndex++;
}
}
//placing pivot to the sort index
Word swap = array[sortIndex];
array[sortIndex] = pivot;
array[end] = swap;
this.sort(array, begin, sortIndex-1);
this.sort(array, sortIndex+1, end);
}
}
Finally, you just use QuickSort helper class to sort your collection of Word and get the sorted output:
public class WordRecommender {
String fileName;
public WordRecommender(String fileName) {
this.fileName = fileName;
}
public static void main(String[] args) {
ArrayList<Word> objectArray = new ArrayList<Word>();
objectArray.add(new Word("people" ,0.8));
objectArray.add(new Word("dogs", 0.4));
objectArray.add(new Word("cats" ,0.6));
QuickSort quickSort = new QuickSort(objectArray.toArray(new Word[]{}));
Word[] sortedWordArray = quickSort.sort();
//output: [people, cats, dogs]
System.out.println(Arrays.asList(sortedWordArray));
}
}
I am facing a problem where I need to sort a String array in alphabetical order. I am able to sort one array, but the problem starts when there are 2 more arrays, that correspond to the first array. Each value in each array should be in the same place, to make information not messed up. After sorting array1, it is in alphabetical order, but i don't have any idea how to make values from array2 and array3 change the positions the same like in array1 after sorting is finished.
My code so far is:
public void sort()
{
boolean finish = false;
while(finish == false){
finish = true;
for(int i=0;i<Country.length-1;i++)
{
int num = 0;
if(Country[i] != null && Country[i + 1] != null)
{
String name1=Country[i]; String name2=Country[i+1];
num=name1.compareTo(name2);
}
else if(Country[i] == null && Country[i + 1] == null){
num = 0;
}
else if(Country[i] == null){
num = 1;
}
else {
num = -1;
}
if(num>0)
{
String temp=Country[i];
Country[i]=Country[i+1];
Country[i+1]=temp;
finish=false;
}
}
}
By far the most recommended way is to re-design your program, and arrange all the related items in a single class. This is what objects are for, after all. Then you can make the object Comparable, give it a compareTo method, and sort it.
But if you are really unable to do that, what you should do is, whenever you exchange any two items in your sort array, make sure you exchange the corresponding items in the other arrays.
So, if you have arrays country, capital and headOfState, you will have to write something like:
String temp=country[i];
country[i]=country[i+1];
country[i+1]=temp;
temp=capital[i];
capital[i]=capital[i+1];
capital[i+1]=temp;
temp=headOfState[i];
headOfState[i]=headOfState[i+1];
headOfState[i+1]=temp;
This way, whenever you move anything in your main array, you'll also be moving the respective item in the other arrays, so they will stay together.
But again, it's much more preferred if you re-designed your program.
Also note the Java language conventions - variable names should not start with a capital letter, only type names should.
If you want all the array to be swaped based on the compare you did in the country array. You can just swap more than one array after one compare.
If(array1[i] > array1[i+1]){
Swap(array1[i],array1[i+1)
Swap(array2[i],array2[i+1])
}
By using a swap function, you can make it more simpler to do swaping in much more array.
You have to swap elements in Country and City arrays simultaneously.
public class BubbleSortTmp {
public String[] Country = {"z", "h", "a"};
public int[] City = {3, 2, 1};
public void printCountry() {
for (String s : Country) {
System.out.printf("%s ", s);
}
System.out.println();
}
public void printCity() {
for (int s : City) {
System.out.printf("%s ", s);
}
System.out.println();
}
public void sort() {
for (int outer = Country.length - 1; outer > 0; outer--) {
for (int inner = 0; inner < outer; inner++) {
if (Country[inner].compareTo(Country[inner+1]) > 0) {
swapCountry(inner, inner+1);
swapCity(inner, inner+1);
}
}
}
}
private void swapCountry(int first, int second) {
String tmp = Country[first];
Country[first] = Country[second];
Country[second] = tmp;
}
private void swapCity(int first, int second) {
int tmp = City[first];
City[first] = City[second];
City[second] = tmp;
}
public static void main(String[] args) {
BubbleSortTmp bs = new BubbleSortTmp();
System.out.println("Before: ");
bs.printCountry();
bs.printCity();
bs.sort();
System.out.println("After: ");
bs.printCountry();
bs.printCity();
}
}
I have been stuck on this problem for so long and i have no idea what to do.
Basically i have a text file with people names then student number then prize money like this:
Green%3243%1000
Kevin%7657%400
Frank%345%10000
Bob%5435%5000
Stefan%31231%1000
Javis%4532%100
IronMan%5435%2000
Lamp%534%3000
What i want to be able to do is sort the array based on the last number.
I tried this abomination (Don't bother reading it its garbage):
boolean flag = true;
String temp;
int temp1;
int temp2;
while (flag){
flag = false;
for(int j=0; j < list.size() -1; j++ ){
System.out.println(list.get(j));
Scanner s = new Scanner(list.get(j)).useDelimiter("%");
s.next();
s.next();
temp1 = s.nextInt();
Scanner s2 = new Scanner(list.get(j+1)).useDelimiter("%");
s2.next();
s2.next();
temp2 = s2.nextInt();
if (temp1 < temp2){
temp = list.get(j);
list.add(j, list.get(j+1));
list.add(j+1,temp);
flag = true;
}
}
}
But its just infinitely looping. My though while making it was just patching array lists into a bubble sort.
If anyone has any ideas and is willing to share them it will be greatly appreciated.
Java is an object-oriented language, so I'll just use objects:
Create a Student object with the three values you want to store (and a toString() method to print them separated by "%":
public class Student {
private final String name;
private final int number;
private final int prizeMoney;
public Student(final String name, final int number, final int prizeMoney) {
this.name = name;
this.number = number;
this.prizeMoney = prizeMoney;
}
#Override
public String toString() {
return name+"%"+number+"%"+prizeMoney;
}
public int getPrizeMoney() {
return prizeMoney;
}
}
Read your lines as Student objects, and store them in a List:
final Scanner scan = new Scanner(new File("/path/to/StudentsList"));
final List<Student> students = new ArrayList<Student>();
while (scan.hasNextLine()) {
final Scanner line = new Scanner(scan.nextLine());
line.useDelimiter("%");
students.add(new Student(line.next(), line.nextInt(), line.nextInt()));
line.close();
}
scan.close();
Order the List with a custom Comparator, and print it:
students.sort(new Comparator<Student>() {
#Override
public int compare(final Student s1, final Student s2) {
return s1.getPrizeMoney()-s2.getPrizeMoney();
}
});
for (final Student student: students)
System.out.println(student);
Output:
Javis%4532%100
Kevin%7657%400
Green%3243%1000
Stefan%31231%1000
IronMan%5435%2000
Lamp%534%3000
Bob%5435%5000
Frank%345%10000
Here's something for you to get head started.
Create a map for prize money => line as key/value pair
Read each line in the file, parse it and put key/value pair in the above map
Once your map is ready, convert the keys entry set into the collections like list
Sort the collections, using Collections.sort()
Iterate over the created map, and for each value in the collection get the corresponding value from the map.
Hope this helps you to get the workflow.
Id consider creating a 3d array here 8x8x8 from right to left in the array is row, col, and in so [0][0][1] is block one or kevin [0][1][1] is 7657 [1][1][1] is 400. I like this way because not only does it give each 'item' an array it allows you to keep it organized and easily accessable
Student's names(String[]) and corresponding marks(int[]) are stored in different arrays.
How may I iterate over both arrays together using for each loop in Java ?
void list() {
for(String s:studentNames) {
System.out.println(s); //I want to print from marks[] alongside.
}
}
One trivial way could be using index variable in the same loop. Is there a good way to do?
You need to do it using the regular for loop with an index, like this:
if (marks.length != studentNames.length) {
... // Something is wrong!
}
// This assumes that studentNames and marks have identical lengths
for (int i = 0 ; i != marks.length ; i++) {
System.out.println(studentNames[i]);
System.out.println(marks[i]);
}
A better approach would be using a class to store a student along with his/her marks, like this:
class StudentMark {
private String name;
private int mark;
public StudentMark(String n, int m) {name=n; mark=m; }
public String getName() {return name;}
public int getMark() {return mark;}
}
for (StudentMark sm : arrayOfStudentsAndTheirMarks) {
System.out.println(sm.getName());
System.out.println(sm.getMark());
}
The underlying problem is actually that you should tie both of the arrays together and iterate across just one array.
Here is a VERY simplistic demonstration - you should use getters and setters and you should also use a List instead of an array but this demonstrates the point:
class Student {
String name;
int mark;
}
Student[] students = new Student[10];
for (Student s : students) {
...
}
If them both have the same size, I would write:
for(int i = 0; i<marks.length; i++) {
String names= studentNames[i]
int mark = marks[i];
}
The other way is to use a verbose for loop statement such as;
int i,j;
for(i = 0, j=0; i<= student.length-1 && j <=grades.length-1; i++,j++)
{
...
}
This question already has answers here:
Array List count to users
(4 answers)
Closed 9 years ago.
I wrote a class that does different things. I am trying to user a loop to count the number of users in an array list. Basically the class is taking information and adding that info regarding students. One of the things being entered is the number of credits being taken by students. Let say I entered 5 students into my array list. two students are taking 5 credits 2 students are taking 6 credits and the last student is taking 9 credits. I created some code in the class, let say that the user wants to know how many students in the array are taking 6 credits. So I created a segment that lets the user enter that number and the class would look in the array and return how many students are taking that number, but its not working. I dont know if this makes sense
System.out.print("Please enter a number of credits:\n");
inputInfo = stdin.readLine().trim();
int credits = Integer.parseInt(inputInfo);
int count = 0;
for (int i = 0; i < studentList.size(); ++i)
{
count++;
}
System.out.println("The number of students who are taking " + credits
+ " credits is: " + count);
break;
You're looping through the array but you're not doing nothing on it.
You should take each student from the list and check the proposed condition. I'm not putting the code because I think that is your homework part.
You will need something like this:
for (int i = 0; i < studentList.size(); i++) {
Student student = studentList.get(i);
if (student.getCredits() == credits) {
count++;
}
}
better use this way to iterate your list:
for (Student student : studentList) {
if (student.getCredits() == credits) {
count++;
}
}
you have ; ++i in your loop, but don't you want i++?
Also you want to check if the credits for a particular student is equal to the credit value inputed by the user. assuming credits for individual students are stored in the arrayList creditList:
int count =0;
for (int i = 0; i < studentList.size(); i++)
count = (creditList.get(i)== credits)?count+1:count;
You need to compare credits against something. Right now, you're just incrementing count every time through the loop (which always results in count == studentList.size()). What you want is to check whether each student is taking that number of credits:
for (int i = 0; i < studentList.size(); ++i) {
if (studentLost.get(i).getNumberOfCredits() == credits) {
count++;
}
}
The above example assumes you've got some kind of Student class with a getNumberOfCredits() method to return the number of credits that student is taking. Without seeing your code, that's my best guess.
Also note that since the position of each student within the list isn't important, you can use an enhanced for-loop to make your code a little cleaner:
for (Student student : studentList) {
if (student.getNumberOfCredits() == credits) {
count++;
}
}
Here a more functional approach with predicates and filters.
public class StudentCredit {
public static void main(String[] args) {
List<Student> students = Arrays.asList(new Student(5), new Student(5),
new Student(6), new Student(6), new Student(9));
final int six = 6;
Predicate<Student> hasSixCredits = new Predicate<Student>() {
public boolean isTrue(Student object) {
return object.getCredit() == six;
}
};
List<Student> studentsWithSix = Filter.filter(students, hasSixCredits);
System.out.println("Number of students with " + six + " credits is: "
+ studentsWithSix.size());
Filter<Student> filter = new Filter<Student>();
List<Student> result = filter.apply(students);
System.out.println("Apply empty filter. #students: " + result.size());
List<Student> otherResult = filter.setPredicate(hasSixCredits).apply(
students);
System.out.println("Apply 6-credits filter. #students: " + otherResult.size());
}
}
class Student {
private final int credit;
public Student(int credit) {
this.credit = credit;
}
public int getCredit() {
return credit;
}
}
interface Predicate<T> {
/* tautology - always true */
public static final Predicate<Object> ALWAYS_TRUE = new Predicate<Object>() {
public boolean isTrue(Object object) {
return true;
}
};
/* contradiction - always false */
public static final Predicate<Object> ALWAYS_FALSE = new Predicate<Object>() {
public boolean isTrue(Object object) {
return false;
}
};
public boolean isTrue(T object);
}
final class Filter<T> {
private Predicate<? super T> predicate = Predicate.ALWAYS_TRUE;
public Filter() {
}
public Filter<T> setPredicate(Predicate<? super T> predicate) {
this.predicate = predicate;
return this;
}
public List<T> apply(List<T> list) {
List<T> filtered = new ArrayList<T>();
for (T element : list)
if (predicate.isTrue(element))
filtered.add(element);
return filtered;
}
public static <T> List<T> filter(List<T> list, Predicate<? super T> predicate) {
return new Filter<T>().setPredicate(predicate).apply(list);
}
}
With this approach you can also create other predicates and you doesn't need to do the counting. Your only concern is the logic of the predicate.