I've gotten the basics of insertion code but I'm stuck on how to compare it with another condition other then (list by A-Z, Z-A)
for the example a list of staff ranks were given :
public static final String[] staffrank = {
"Trainee",
"Junior",
"Senior",
"Administrator"
};
I have a method to compareRank
If it returns 0 means they're of equal rank (staff 1 and staff 2)
if it returns -1 means staff 1 is lower rank than staff 2
if it returns 1 means staff 1 is higher rank than staff 2
Then I have a list of staffs in void main
Staff[] snames;
int countname=0;
snames = new Staff[50];
snames[countname++] = new Staff("Amy","Trainee");
snames[countname++] = new Staff("Annie","Junior");
snames[countname++] = new Staff("Tom","Administrator");
snames[countname++] = new Staff("Dave","Trainee");
snames[countname++] = new Staff("Gary","Junior");
snames[countname++] = new Staff("Donna","Senior");
then the insertion sort compare code
public static void insertionSortbyRank(Staff[] snames, int countname) {
//insertion sort
for(int i =1; i < countname; i++) {
int j = i;
int comparerank = Staff.compareRank(snames[j],snames[j-1]);
String name = snames.getName();
String rank = snames.getRank();
//if staff is lower rank
if(comparerank==-1) {
Then i'm unsure what to put in this while loop
still giving me an unsorted list
while( j >0 && rank.compareRank(list[j], list[j - 1]) == 1))) {
list[j].rank =[j-1].rank;
list.[j].name = [j-1].name;
j--;
}
then the end is replacing the new values
snames[j].name = name;
snames[j].rank = rank;
the output suppose to give : (by order of their ranks from low to highest according to the chart)
Amy, Trainee
Dave, Trainee
Annie, Junior
Gary, Junior
Donna, Senior
Tom, Administrator
Any help would be appreciated..thank you
I would assume that since you've been given a staffrank variable, that you should probably make use of it. However, aside from mentioning it at the top of your question, you make no other use of it that we've been shown...So my assumption is that you've ignored it completely.
I think that's the key to your puzzle here.
Note that I'm ignoring the fact that String arrays are not the best representation (I'd go for an enum or something like a class...Potentially implementing Comparable<StaffRank> somewhere...But this is a test question as noted, after all...)
You could make a function like this:
public static final int compareRank(String[] ranks, String rank) {
for (int i=0; i<ranks.length; i++) {
String string = ranks[i];
if string.equals(rank) return i;
}
return -1;
}
Which will return an integer between -1 and (ranks.length -1) which you can use for comparison. The smaller the number the more junior the rank.
Inside your while loop you'll have to compare each staff and swap them if the "i"-th staff is greater than the "i+1"-th staff.
for (int i=0; i<(snames.length-1); i++) {
Staff sname1 = sname[i];
Staff sname2 = sname[i+1]
//compare sname1 to sname2 and swap if sname1 > sname2
}
Related
Okay. I'm effectively a -total- beginner to coding (taken some classes but a slow/dense learner) and the answer is probably ridiculously simple. I have one string array that has names and another that has the scores associated.
names[0] = blinky
scores[0] = 42 (blinky's score)
names[1] = inky
scores[1] = 37 (inky's score)
in the for loop i calls the number (index number? I'm horrible with terms. The only thing that ever seems to make sense is the code itself). Anyway, I want to be able to preserve i.
I want to make a list that puts the names with the scores in order from highest to lowest.
I don't know if using util.Arrays or anything that will automatically sort will help. I believe I'll have to manually have to sort them in order to keep the names and numbers aligned
//Example
String[] names = {"Blinky","Inky","Pinky","Clyde"};
int[] scores = {42,37,67,50};
for (int = 0; i < scores.length; i++){
System.out.println("what do?")
}
How would I go about making a list that puts the names in order? Simpler the better.
I'd be very appreciative of help.
Edit: I'd like to thank all of you for your help! :)
To get the results below, you can try out the following codes.
Unsorted
---------
Blinky, score=42
Inky, score=37
Pinky, score=67
Clyde, score=50
sort by score ascending
Inky, score=37
Blinky, score=42
Clyde, score=50
Pinky, score=67
sort by Name ascending
Blinky, score=42
Clyde, score=50
Inky, score=37
Pinky, score=67
1) create a new class called NameScoreEntity to store both variables together (this way when you sort, both the names and scores are done at the same time)
public class NameScoreEntity {
String name;
int score;
public NameScoreEntity(String name, int score) {
this.name = name;
this.score = score;
}
#Override
public String toString() {
return name + ", score=" + score;
}
}
2) you then create an arrayList of your new class to copy your two arrays into.
String[] names = {"Blinky","Inky","Pinky","Clyde"};
int[] scores = {42,37,67,50};
List<NameScoreEntity> data = new ArrayList<>(); // your data is now stored here
for (int i= 0; i < scores.length; i++){
data.add(new NameScoreEntity(names[i], scores[i]));
}
//print unsorted
System.out.println("Unsorted\n---------");
for (NameScoreEntity e : data) {
System.out.println(e);
}
3) finally, you just use the sort() method that is available in the list to do your sorting.
System.out.println("sort by score ascending");
data.sort(new Comparator<NameScoreEntity>() {
#Override
public int compare(NameScoreEntity o1, NameScoreEntity o2) {
return Integer.compare(o1.score, o2.score); //for descending just swap o1 & o2
}
});
for (NameScoreEntity e : data) {
System.out.println(e);
}
System.out.println("sort by Name ascending");
data.sort(new Comparator<NameScoreEntity>() {
#Override
public int compare(NameScoreEntity o1, NameScoreEntity o2) {
return o1.name.compareTo(o2.name) ;//for descending just swap o1 & o2
}
});
for (NameScoreEntity e : data) {
System.out.println(e);
}
You should use a TreeMap, which will always keep the orders between your scores and match the corresponding String.
// new TreeMap that sorts from highest to lowest
Map<Integer, String> map = new TreeMap<>(Collections.reverseOrder());
Then just put all your values into the Map using the loop you already have:
for(int i = 0; i < scores.length; i++)
map.put(scores[i], names[i]);
And finally you can just print the Map:
System.out.println(map);
Result:
{67=Pinky, 50=Clyde, 42=Blinky, 37=Inky}
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;
}
...
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);
So I had a delimited file that I read into an array.
array[0] is the boxID (double)
and
array[1] is the movieID (double)
I have no clue how I'd be able to sort my array by these two doubles. Any comments? I've tried looking at other questions on this website but I just got confused by them. I'm currently in my first programming class.
Movies[] newMasterMovies = new Movies[200];
int newMasterCount = 0;
int masterCount = 0;
int updateCount = 0;
while (updateCount < updateTotalCounter || masterCount < masterTotalCounter) {
String updateCompare = updateMovies[updateCount].getBoxID() + updateMovies[updateCount].getMovieID();
String masterCompare = masterMovies[masterCount].getBoxID() + masterMovies[masterCount].getMovieID();
int compare = updateCompare.compareTo(masterCompare);
if (compare > 0) {
newMasterMovies[newMasterCount] = masterMovies[masterCount];
masterCount++;
newMasterCount++;
}
if (updateMovies[updateCount].getActionCode() == "A") {
newMasterMovies[newMasterCount] = updateMovies[updateCount];
updateCount++;
newMasterCount++;
}
if (updateMovies[updateCount].getActionCode() == "D") {
updateCount++;
masterCount++;
}
if (updateMovies[updateCount].getActionCode() == "C") {
newMasterMovies[newMasterCount] = updateMovies[updateCount];
updateCount++;
newMasterCount++;
masterCount++;
}
}
That is what my array looks like that I am trying to sort. I tried to do a selection sort but got confused since I want to sort by two properties, not just one.
This guy here does a wonders
Arrays.sort(iArr);
Here is what it can do:
Here is an example code
public class ArrayDemo {
public static void main(String[] args) {
// initializing unsorted int array
int iArr[] = {2, 1, 9, 6, 4};
// let us print all the elements available in list
for (int number : iArr) {
System.out.println("Number = " + number);
}
// sorting array
Arrays.sort(iArr);
// let us print all the elements available in list
System.out.println("The sorted int array is:");
for (int number : iArr) {
System.out.println("Number = " + number);
}
}
}
And the results should be like this
Number = 2
Number = 1
Number = 9
Number = 6
Number = 4
The sorted int array is:
Number = 1
Number = 2
Number = 4
Number = 6
Number = 9
Hopes this helps some
To simply sort your Movies[] you can use Arrays.sort and use a custom Comparator. Like this:
Arrays.sort(masterMovies, new Comparator<Movies>() {
#Override
public int compare(Movies o1, Movies o2) {
// compare boxID
// compare movieID
return 0; // return result
}
});
Arrays.sort use merge sort or binary insertion sort which are both more stable and faster than selection sort.
If you insist to do your selection sort, try to edit yor class Movies to implement Comparable interface, like this: class Movies implements Comparable<Movies>. And implement compareTo method like this:
#Override
public int compareTo(Movies o) {
// compare boxID
// compare movieID
return 0; // return result
}
And change your old compare code int compare = updateCompare.compareTo(masterCompare); to int compare=updateMovies[updateCount].compareTo(masterMovies[masterCount]);, then go on.
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.