how to input values into ArrayList alphabetically - java

I'm given the task of adding a value into an ArrayList alphabetically (by lastname first, and firstname if lastnames are the same),I'm not allowed to sort the ArrayList once all the inputs are given. What I am suppose to do is determine the location of where the value should be each time an input is given and place it there. Example values: Inputs are {John Doe, Bryan Sully, Harry Ache, Ali Doe, Bry Dyre} , Output should be {Harry Ache, Ali Doe, John Doe, Bry Dyre, Bryan Sully}. However, in cases where there are two of the same last names, what will occur is {Harry Ache, Ali Doe, Bry Dyre, John Doe, Bryan Sully}, why?
ArrayList<Person> list = new ArrayList<Person>();
public void addPerson(Person p){
if(list.size() == 0){
list.add(p);
} else{
for(Person pp: list){
int getIndex = list.indexOf(pp);
int lOrder = p.getLastName().compareTo(pp.getLastName());
if(lOrder > 0){
list.add(getIndex + 1, p);
break;
} else if(lOrder == 0){
int fOrder = p.getFirstName().compareTo(pp.getFirstName());
if(fOrder > 0){
list.add(getIndex, p);
break;
} else {
list.add(getIndex + 1, p);
break;
}
} else {
list.add(getIndex, p);
break;
}
}
}
}

One issue with your code is that you are making an insertion after a single iteration of your loop, inserting Person p only in comparison to the first Person in the list.
Here is an improved implementation:
public void addPerson(Person person) {
if (list.isEmpty()) {
list.add(p);
} else {
// the position where you will insert the Person;
// default value is list.size(), so it can be added to the end
int position = list.size();
Person p;
for (int i = 0; i < list.size(); i++) {
p = list.get(i);
// if the comparison result is > 0, you found the first Person
// in the list that comes alphabetically after;
// Insert person before it, at position i
if (compare(p, person) > 0) {
position = i;
break; // only break now that you've found the insert position
}
}
list.add(person, position);
}
}
/**
* #return 0 if both Persons p1 & p2 have the same names,
* a positive number if p1 is lexicographically greater than p2,
* or a negative number if p1 is lexicographically less than p2
*/
private int compare(Person p1, Person p2) {
int result = p1.getLastName().compareTo(p2.getLastName());
if (result == 0) {
result = p1.getFirstName().compareTo(p2.getFirstName());
}
return result;
}
As others suggested, implementing the Comparable interface in Person if possible can also help create a cleaner implementation.

Few improvements.
You are better off if you can iterate the list using the index like
for(int i = 0; i < array.size(); i++)
You need not have to check for lastName and firstName separately. You can just compare both of them together (p.lastName + p.firstName).compareTo(pp.lastName + pp.firstName) and act upon the result. As you already have the index of the current element, you just have to check if you just insert the new item on the same index or not.
Here is a sample implementation
static void addPerson(Person person) {
for (int i = 0; i < sortedList.size(); i++) {
var existingPerson = sortedList.get(i);
var compareResult = compare(existingPerson, person);
if (compareResult > 0) {
sortedList.add(i, person);
return;
}
}
sortedList.add(person);
}
static int compare(Person p1, Person p2) {
return (p1.lastName + p1.firstName).compareTo(p2.lastName + p2.firstName);
}

The problem with your algorithm, is that you always looking at the first person in the target list, and making decisions solely on that person, notice how all your "branches" have a break statement at the end?
I understand your "reason" for adding all those break statements, those make sure the new person always gets inserted into the list, when it doesn't match, the same reason why your first check if the list is empty.
To properly implement an "insertion sort" system, you actually need to loop over all the indexes of your list.
An simple "insertion sort" algorithm looks like this:
Loop over the target list
Check if existing entry is "bigger" than the newly person
If the existing entry is bigger, we need to move that entry (all all remaining entries) up 1 spot, insert out entry, and abort
If we are done looping, and we didn't abort in the above steps, insert our entry at the end of the list.
ArrayList<Person> list = new ArrayList<Person>();
public void addPerson(Person p){
// Loop
int size = list.size();
for(int getIndex = 0; getIndex < size; getIndex++){
Person pp = list.get(getIndex);
// Compare
int compare = p.getLastName().compareTo(pp.getLastName());
if (compare > 0) {
continue;
} else if(compare == 0) {
if (p.getFirstName().compareTo(pp.getFirstName()) > 0) {
continue;
}
}
// Add in existing slot
list.add(getIndex, p);
return;
}
// Add at the end
list.add(p);
}
One hard part of this, is the fact that we have to compare on 2 things for a single person, this makes the compare logic way harder than it needs to be. This can be solved by factoring this part out to a "helper" comparator that does this logic merging for us:
Comparator<Person> compare = Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName);
// Then, inside the above loop:
...
// Compare
if (compare.compare(p, pp) > 0) {
continue;
}
...

Related

Insertion Sorting compareTo()

So I have a list of objects that I would like to sort based on the trait of each name of the object (In alphabetical order). We are required to have it "Roughly" in alphabetical order, so I have what I thought was a mediocre implementation of the insertion sorting algorithm. However, I'm only able to sort one item properly alphabetically. I have been at this for hours and seem to have hit a road block.
public void sort(){
int i=1;
while(list[i]!=null) { //while there is an element in the array
String one=list[i-1].getName(); //get the name of the "first object"
String two=list[i].getName(); //get the name of the "second object"
if(two.compareTo(one)==0){ // if equal move on
i++;
}
else if(two.compareTo(one)<0){// two is before one
Contact temp =list[i-1]; //store this temporarily
list[i-1]=list[i]; //swap them
list[i]=temp; //put temp back where it belongs
i++; //check next elements
}
i++
}
}
Here is what is list, before, and after the sort...http://image.prntscr.com/image/698cf44309ee43c29532ebe71a4925fe.png
First, you have to understand how insertion sort works.
You pick an element from the unsorted half of the list (O(n))
Try to insert the newly picked element to the sorted half of the list (O(n))
So, insertion sort is O(n^2), meaning it requires a nested loop, at least.
Here is a modified version:
int i = 1;
while(list[i] != null) {
// i divides sorted and unsorted
// try to insert i to the right place, so loop j from i-1 to 0
int j = i;
while (j > 0) {
String one = list[j-1].getName();
String two = list[j].getName();
int cmp = one.compareTo(two);
if (cmp <= 0) {
break;
}
Contact temp = list[j-1];
list[j-1] = list[j];
list[j] = temp;
--j;
}
++i;
}
There are many ways to implement insertion sort. I'll explain you a simpler way by which you can sort your array of objects by name as you have explained.
The key properties of Insertion sort is:
Insertion sort starts from he left end of the array and advances to
right.
This sorting mechanism will not look into elements on the right,
rather it focuses on the current encountered item and drags back
that item to it's correct position.
Let's code up keeping these things in mind!!
/*
* Performs Insertion sort on given array of contacts!!
*/
public static Contact[] sortContacts(Contact[] contacts){
int n = contacts.length;
// Advance the pointer to right
for(int i = 0; i < n; i++){
/*
* Compare current item with previous item.
* If current item is not in it's correct position,
* swap until it's dragged back to it's correct position.
* (Ascending order!!)
*/
for(int j = i; j > 0; j--){
if(less(contacts[j], contacts[j - 1])){
swap(contacts, j, j - 1);
}else{
break;
}
}
}
return contacts;
}
private static boolean less(Contact a, Contact b){
return a.getName().compareTo(b.getName()) < 0;
}
private static void swap(Contact[] contacts, int i, int j){
Contact temp = contacts[i];
contacts[i] = contacts[j];
contacts[j] = temp;
}
These three methods facilitates your sorting!!
Now to test it, let's create some contacts and sort them!!
Contact one = new Contact();
one.setName("tony");
one.setPhone("6666");
one.setMail("kkk#lll.com");
Contact two = new Contact();
two.setName("steve");
two.setPhone("777");
two.setMail("rrr#mmm.com");
Contact three = new Contact();
three.setName("clint");
three.setPhone("333");
three.setMail("ggg#sss.com");
Contact four = new Contact();
four.setName("bruce");
four.setPhone("222");
four.setMail("bbb#ccc.com");
Let's sort:
Contact[] res = Insertion.sortContacts(new Contact[]{one,two,three,four});
for(Contact c : res){
System.out.println(c);
}
This produces the output:
Contact [name=bruce, mail=bbb#ccc.com, phone=222]
Contact [name=clint, mail=ggg#sss.com, phone=333]
Contact [name=steve, mail=rrr#mmm.com, phone=777]
Contact [name=tony, mail=kkk#lll.com, phone=6666]
Which is sorted based on names of each contact!!
I hope this is what you were trying to achieve
You can use interface Comparable for your class.
Example:
public class Contact implements Comparable<Contact>
// ...
public int compareTo(Contact other) {
return getName().compareTo(other.getName());
}
}
Then if list is an array:
Arrays.sort(list);

Java - How to implement functions in a heap-based priority queue

For a programming assignment, I have been working on creating a program that reads an input file and sorts the data inside using a self-made max heap priority queue. The data file has lines that either read "insert [a name] [a number]", or "remove". For this priority queue, we need to make a function for inserting and removing objects. Each object in the queue contains the name as a string, and the priority as a integer. I have to implement this heap based on an array with a size of 255.
My question is, I'm having difficulty implementing my insert and remove functions to work as specified. I'll provide 1) how they need to work, 2) pseudocode I've made, and 3) the actual Java code I've implemented. Both of my functions do not work exactly as I intend for them to, so I could use some direction from more experienced programmers.
1) insert(name, priority): this function should take a name of type string and a priority of type integer, and inserts them into the priority queue.
remove(): this function should remove the object with the highest priority value and return the name string from the object.
2) As background, I have three classes for this program: First, the "main" class containing implementation for reading the file and using the functions. Second, the "name" class, which creates the name object containing the name string and priority int , a constructor, and a compareTo method for comparing the priority values of two objects. Third, the "priorityqueue" class, contains the insert and remove functions. Now, here is the pseudocode I made for those two functions:
insert:
Check if the array is full (when num = 255), throw if true
Create the object from the input file with a name string and priority int
Insert the object at num
Use a while loop to swap the two objects at insertion
Update num (num++)
remove:
Save the first object
Move the last object to the first
Update num (num--)
Use a while loop to determine the larger child and return it.
3) Here is the code I have so far. I'll provide my name and priority queue classes, in case my name class is what's giving me trouble.
Priority Queue class:
public class PriorityQueue
{
int num; //amount of things in array
int idx; //index of current name object
Name[] names = new Name[255];
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
}
Name class:
public class Name implements Comparable
{
String name;
int priority;
public Name(String n, int i)
{
name = n;
priority = i;
}
public boolean CompareTo(Name obj)
{
if(priority < obj.priority)
{
return false;
}
else if(priority > obj.priority)
{
return true;
}
return true;
}
}
I appreciate any help. Thanks!
Several problems. First, in your insert method:
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
The while (num != 255) shouldn't be there. You should check to see if num == 255, and throw an exception if it is.
Then, you need to initialize idx. That is:
Name addName = new Name(name, priority);
names[num] = addName;
idx = num;
num++;
And your while condition should use && rather than ||. Otherwise you'll do the swap every time idx is not equal to 0.
In your remove method:
public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]) > 0)
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
You don't want names[idx] there, because you don't know what idx is. You want:
names[0] = names[num-1]; // get last item in the heap
Your while condition here is goofy. Math.max(2*idx+1,2*idx+2) will always return 2*idx+2, unless idx is negative. And, again, you haven't even initialized idx. What you want here is:
idx = 0;
while (idx < num)
Now, what you're trying to do is see if names[idx] is smaller than either of its children. And, if so, select the largest of the two children to swap it with. So:
while (idx < num)
{
int largestChild = idx*2+1;
if (largestChild >= num) break; // idx is at a leaf level
if (largestChild+1 < num)
{
// compare the two children
if (names[largestChild].compareTo(names[largestChild+1]) < 0)
{
largestChild = largestChild+1;
}
}
if (names[idx] < names[largestChild])
{
// swap, moving the item down
temp = names[idx];
names[idx] = names[largestChild];
names[largestChild] = temp;
idx = largestChild;
}
else
{
// item is in the proper place
break;
}
}
I would suggest making idx a method-scoped variable in both methods. There's no need for it to be a global, and making it local to the methods forces you to initialize it before you use it, rather than potentially (as in your existing code) using a stale value.
I think you need to change your Name class's CompareTo function. The Comparable compareTo function must return:
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
So you should have:
public boolean CompareTo(Name obj)
{
if(priority < obj.priority)
{
return -1;
}
if (priority > obj.priority)
{
return 1;
}
return 0;
}

Removing Duplicate Entries in Array - Java

For Java practice, I am trying to create a method inside my EmployeesDirectory Class that:
Removes Duplicate entries from the array
The array should be the same length after removing duplicates
Non-Empty entries should be making a contiguous sequence at the beginning of the array - and the actualNum should keep a record of the entries
Duplicate Means: Same Name, Position and Salary
Here is my Current Code:
I am unsure on how to implement this - any help would be appreciated
class EmployeeDirectory {
private Employee dir[];
private int size;
private int actualNum;
public EmployeeDirectory(int n) {
this.size = n;
dir = new Employee[size];
}
public boolean add(String name, String position, double salary) {
if (dir[size-1] != null) {
dir[actualNum] = new Employee(name, position, salary);
actualNum++;
return true;
} else {
return false;
}
}
}
I'd rather you did not write a distinct method for removing duplicates. If I were you, I would search for duplicates in add method and then instantly decide whether I need to add Employee.
Also, why don't you use Sets (link for HashSet) instead of arrays for your purpose? Sets by their own definition disallow adding duplicates, so they seem to be appropriate as a solution
First of all, Override equals and hashCode methods in Employee class as follow
#Override
public boolean equals(Object other) {
if(this == other) return true;
if(other == null || (this.getClass() != other.getClass())){
return false;
}
Employee guest = (Employee) other;
return Objects.equals(guest.name, name)
&& Objects.equals(guest.position, position)
&& Objects.equals(guest.salary, salary);
}
#Override
public int hashCode() {
return Arrays.hashCode(new Object[] {
name,
position,
salary
});
}
Then you can use Stream API distinct method to remove duplicates
Returns a stream consisting of the distinct elements (according to
Object.equals(Object)) of this stream.
You can do it like so
Employee e1 = new Employee("John", "developer", 2000);
Employee e2 = new Employee("John", "developer", 2000);
Employee e3 = new Employee("Fres", "designer", 1500);
Employee[] allEmployees = new Employee[100];
allEmployees[0] = e1;
allEmployees[1] = e2;
allEmployees[2] = e3;
allEmployees = Arrays.asList(allEmployees).stream().distinct()
.toArray(Employee[]::new);
Arrays.asList(allEmployees).forEach(System.out::println);
Output: (keeping both empty and non-empty entries)
John developer 2000.0
Fres designer 1500.0
null
Unfortunately, I have not got the Employee class to verify my code, but try this:
void removeDuplicates() {
int length = dir.length;
HashSet set = new HashSet(Arrays.asList(dir));
dir = new Employee[length];
Employee[] temp = (Employee[]) set.toArray();
for (int index = 0; index < temp.length; index++)
dir[index] = temp[index];
}
The code must remain the size of array after deletion the duplicates. At the beginning of array there must be valid Employees, at the end - nulls.
And don't forget to add this at the beginning of your .java file
import java.util.Arrays;
import java.util.HashSet;
If your task states as "remove duplicates from array" (i. e. you cannot use ArrayList or control when adding items), you can use the following approach:
public void removeDuplicates() {
Set<Employee> d = new HashSet<>(); // here to store distinct items
int shift = 0;
for (int i = 0; i > dir.length; i++) {
if (d.contains(dir[i])) { // duplicate, shift += 1
shift++;
} else { // distinct
d.add(dir[i]); // copy to `d` set
dir[i - shift] = dir[i]; // move item left
}
}
for (int i = d.size(); i < dir.length; i++)
dir[i] = null; // fill rest of array with nulls
actualNum = d.size();
}
Here, shift variable stores number of duplicates found in the array so far. Every distinct item is moved to shift positions left in order to make sequence continuous while keeping initial ordering. Then remaining items are altered to nulls.
To make hash-based collections work with Employee instances correctly, you also need to override hashCode() and equals() methods as follows:
public class Employee {
//...
#Override
public int hashCode() {
return Objects.hash(name, position, salary);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (!o.getType().equals(this.getType()) return false;
Employee e = (Employee) o;
return Objects.equals(e.name, name)
&& Objects.equals(e.position, position)
&& Objects.equals(e.salary, salary); // or e.salary == salary, if it primitive type
}
}

Using a method to sort a Singly Linked List in Java

Implementing a Linked List, store up to 10 names, ordered in first in First Out. Then implement two methods, one of which to sort it alphabetically by last names. This is where I am having some trouble. Here is what I tried:
Recursion. The method calls two nodes, compare them, swap if needed and then calls itself. Doesn't work with odd number of names and tends to be full bugs.
Collection but I don't know enough about it to use it effectively.
Sorting algorithms (ex. bubble sort): I can go though the list but have a hard time getting the nodes to swap.
My question is: What is the easiest way to do this?
public class List
{
public class Link
{
public String firstName;
public String middleName;
public String lastName;
public Link next = null;
Link(String f, String m, String l)
{
firstName = f;
middleName = m;
lastName = l;
}
}
private Link first_;
private Link last_;
List()
{
first_ = null;
last_ = null;
}
public boolean isEmpty()
{
return first_ == null;
}
public void insertFront(String f, String m, String l)
{
Link name = new Link(f, m, l);
if (first_ == null)
{
first_ = name;
last_ = name;
}
else
{
last_.next = name;
last_ = last_.next;
}
}
public String removeFront()
{
String f = first_.firstName;
String m = first_.middleName;
String l = first_.lastName;
first_ = first_.next;
return f + " " + m + " " + l;
}
public String findMiddle(String f, String l)
{
Link current = first_;
while (current != null && current.firstName.compareTo(f) != 0 && current.lastName.compareTo(l) != 0)
{
current = current.next;
}
if (current == null)
{
return "Not in list";
}
return "That person's middle name is " + current.middleName;
}
}
public class NamesOfFriends
{
public static void main(String[] args)
{
List listOfnames = new List();
Scanner in = new Scanner(System.in);
for(int i = 0; i < 3; i++)
{
if(i == 0)
{
System.out.println("Please enter the first, middle and last name?");
listOfnames.insertFront(in.next(), in.next(),in.next());
}
else
{
System.out.println("Please enter the next first, middle and last name");
listOfnames.insertFront(in.next(), in.next(),in.next());
}
}
System.out.println("To find the middle name, please enter the first and last name of the person.");
System.out.println(listOfnames.findMiddle(in.next(),in.next()));
}
}
Edit
After working on it a bit, I figured out how to go about sorting it. For that purpose, I am trying to implement a remove method that can remove a node anywhere on the list. While it does compile, it doesn't do anything when I run the program.
public Link remove(String lastName)
{
Link current_ = first_;
Link prior_ = null;
Link temp_ = null;
while (current_ != null && current_.lastName.compareTo(lastName) != 0)
{
prior_ = current_;
current_ = current_.next;
}
if (current_ != null)
{
if (current_ == last_)
{
temp_ = last_;
last_ = prior_;
}
else if (prior_ == null)
{
temp_ = first_;
first_ = first_.next;
}
}
else
{
temp_ = current_;
prior_.next = current_.next;
}
return temp_;
}
2: Collections is the easiest, but it seems to be not allowed in your homework
3: BubbleSort is easy but the worst known sorting algo, however for your homework it probably is ok
1: This is the same as bubble sort, but is prefered to be done without recursion
In BubbleSort you loop through your elements again and again till no swaps are neeeded anymore, then you are ready.
Collection is the easiest way to accomplish this.
Implement Comparable
Override hashcode and equals
Collection.sort()
You already has the linked list implemented, that is good.
Have you considered implementing MergeSort as the sorting algorithm? Being the divide&conquer algorithm, you will always end up with only two elements to form a list with.
The merge part is going to be trickier, but also easy. Basically you just create a new list and start filling it up with elements you get by comparing the first values of the two merging sets.
So for instance if you have two sets to merge:
[A]->[C]->[D]
[B]->[E]->[F]
the mergin process will go:
[A]
[C]->[D]
[B]->[E]->[F]
[A]->[B]
[C]->[D]
[E]->[F]
[A]->[B]->[C]
[D]
[E]->[F]
[A]->[B]->[C]->[D]
[E]->[F]
[A]->[B]->[C]->[D]->[E]
[F]
[A]->[B]->[C]->[D]->[E]->[F]

How to sort three arrays in java?

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.

Categories