Checking an array for descending order - java

I am writing code to check if my array is in ascending or descending order. If the boolean 'ascending' is true, then I check if it is ascending. If it is false, then I check for descending. I need help checking whether the array is descending or not... I have the code to check ascending which is written below:
protected boolean isSorted(boolean ascending) {
boolean result = false;
if (ascending) {
for (int i=0;i<data.length-1;i++) {
if(data[i] < data[i+1]) {
result = true;
} else if(data[i] > data[i+1]) {
result = false;
}
}
} else {
//code to check for descending order
}
}

The first part of the if (the "ascending" check) is wrong, it should be:
for (int i = 0; i < data.length-1; i++) {
if (data[i] > data[i+1]) {
return false;
}
}
return true;
Conversely, the descending check should be (and notice that it's enough to change the direction of the comparison operator):
for (int i = 0; i < data.length-1; i++) {
if (data[i] < data[i+1]) {
return false;
}
}
return true;
In both cases, you have to break out of the loop as soon as you find a single pair of numbers that do not hold the ascending-or-descending property, and only return true after the loop exits.

You can cheat and do it in one loop if you like and remove one addition:
protected boolean isSorted(boolean ascending) {
for (int i = 1; i < data.length; i++) {
if (data[i-1] == data[i]) {
continue;
}
if ((data[i-1] > data[i]) == ascending) {
return false;
}
}
return true;
}
NOTE: I am building on the code by #OscarLopez so upvote his if you upvote mine.

To check if ArrayList<Integer> is in descending order try this:
boolean isSorted(ArrayList<Integer> list){
boolean sorted = true;
for (int i = 1; i < list.size(); i++) {
if (list.get(i-1) >= (list.get(i)) ) {
sorted = true;
} else {
return false;
} // if else ends
} // for "i" ends
return sorted;
}

Related

What is wrong with my code for this array?

I am doing a online course and I have a problem. i do not understand what is wrong with my code. Can you please take a look and give me a hint? I don't get why the last test is not working. When they add the cat in pos 0 to the list, the list should become [cat, ape, dog, zebra], no?
import java.util.ArrayList;
public class ArrayListMethods
{
ArrayList<String> list; //instance variable
/**
* Constructor for objects of class ArrayListMethods
*/
public ArrayListMethods(ArrayList<String> arrayList)
{
// initialise instance variables
list = arrayList;
}
/**
* Determines if the array list is sorted (do not sort)
* When Strings are sorted, they are in alphabetical order
* Use the compareTo method to determine which string comes first
* You can look at the String compareTo method in the Java API
* #return true if the array list is sorted else false.
*/
public boolean isSorted()
{
boolean sorted = true;
// TODO: Determine if the array is sorted.
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).compareTo(list.get(i + 1)) < 0){
sorted = true;
}
else {
sorted = false;
}
}
return sorted;
}
}
The tester class used to test the code has this:
import java.util.ArrayList;
public class ArrayListMethodsTester
{
public static void main(String[] args)
{
//set up
ArrayList<String> animals = new ArrayList<String>();
ArrayListMethods zoo = new ArrayListMethods(animals);
zoo.list.add("ape");
zoo.list.add("dog");
soo.list.add("zebra");
//test isSorted
System.out.println(zoo.isSorted());
System.out.println("Expected: true");
zoo.list.add("cat");
System.out.println(zoo.isSorted());
System.out.println("Expected: false");
zoo.list.remove("cat");
zoo.list.add(0,"cat");
System.out.println(zoo.isSorted());
System.out.println("Expected: false");
}
}
You isSorted method only returns false if the last two elements are not sorted. You should add a break after setting the sorted variable to false:
public boolean isSorted() {
boolean sorted = true;
// TODO: Determine if the array is sorted.
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).compareTo(list.get(i + 1)) < 0){
sorted = true;
}
else {
sorted = false;
break; // Add break here
}
}
return sorted;
}
Or more simply:
public boolean isSorted() {
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).compareTo(list.get(i + 1)) > 0){
return false;
}
}
return true;
}
The problem is inside your isSorted() method, you are setting the result as false in the first iteration (because cat is not sorted). But in the second iteration it sets the result as true because "ape" is sorted compared with "dog"
The solution is to finish the process once a false is founded.
So change this:
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).compareTo(list.get(i + 1)) < 0){
sorted = true;
}
else {
sorted = false;
}
}
For this:
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).compareTo(list.get(i + 1)) < 0){
sorted = true;
}
else {
return false;
}
}
And it will work fine and it will also improve the performance, since there is no need to check the whole array. If the first couple of elements are not sorted, then the array is not sorted

Finding Uniqueness (duplicates)

Im having trouble with my isUnique method. Either I'm making a logical error or a syntax error, or both. I have to make sure that every user input I get is Unique. Everything else I have done is correct but that method. I was using the debugger and I've noticed that the "number" doesn't change as the user input changes but I am new and kinda lost. Assigment: Enter 5 numbers and test for validity and uniqueness. If not valid do not count towards 5 numbers. If not unique count towards 5 numbers but count number of unique and print "not unique" if not unique.
import java.util.Scanner;
public class Assignment4Part2 {
public static void main(String[] args) {
int[] numbers = new int[5];
System.out.println("Enter an integer (50-100): ");
Scanner input = new Scanner(System.in);
int uniqueCount = 0;
for (int i = 0; i < numbers.length;) {
{
numbers[i] = input.nextInt();
if (isValid(numbers[i]) == true) {
i++;
if (isUnique(numbers, numbers[i]) == true) {
uniqueCount++;
System.out.printf("Unique so far: %d ", uniqueCount);
}
if (isUnique(numbers, numbers[i]) == false) {
System.out.println("That's not unique.\n");
}
}
}
}
for (int i = 0; i < numbers.length; i++)
{
System.out.print(numbers[i] + " ");
}
}
public static boolean isValid(int array) {
if (array <= 100 & array >= 50) {
return true;
} else {
System.out.println(" ***Invalid Number\n");
return false;
}
}
public static boolean isUnique(int[] array, int numbers) {
for (int i = 0; i < array.length; i++) {
if (array[i] == numbers) {
return false;
} else {
return true;
}
}
return false;
}
}
some things i notice:
for (int i = 0; i < numbers.length;) {
{
numbers[i] = input.nextInt();
if (isValid(numbers[i]) == true) {
//i++; // in case you increment here, you do it before is unqique is true... so next isUnique is of an emtpy (null) numbers[i]
if (isUnique(numbers, numbers[i]) == true) {
uniqueCount++;
System.out.printf("Unique so far: %d ", uniqueCount);
//continue here
i++;
}// why not an else?
//if (isUnique(numbers, numbers[i]) == false) {
else {
System.out.println("That's not unique.\n");
}
}
}
}
and the is unique....
public static boolean isUnique(int[] array, int numbers) {
// here the given number is already in the array, so never unique....
// this will always return false, because the input is already in the array
for (int i = 0; i < array.length; i++) {
if (array[i] == numbers) {
return false;
} else {
return true;
}
}
return false;
}
so use:
for (int i = 0; i < numbers.length;) {
{
// use a temp value before putting it in the array
int input = input.nextInt();
if (isValid(input) == true) {
//i++; // in case you increment here, you do it before is unqique is true... so next isUnique is of an emtpy (null) numbers[i]
if (isUnique(numbers, input) == true) {
uniqueCount++;
numbers[i] = input
System.out.printf("Unique so far: %d ", uniqueCount);
//continue here
i++;
}// why not an else?
//if (isUnique(numbers, numbers[i]) == false) {
else {
System.out.println("That's not unique.\n");
}
}
}
}
and in the is unique function....
if (array[i] == numbers) {
while not all numbers are filled in... this compares:
if(null == numbers){
so will be shorter to add in front:
if(array[i]==null){
break;
}
because the rest is still empty
The error is in the for in your method isUnique, during the first iteration you compare your the given number with the first value and if they dont match you already return true so the loop can't check any of the remaining numbers.
Just remove the else parte in that if and change the last return out of the loop to a true instead of false.
This way only until you checked the the whole array you will be sure the number is unique.
I would also sugest you send to that methis uniqueCount so you dont check the whole array, but just the amount of numbers already registered.

Sorting an ArrayList so that certain numbers go first, and the order is otherwise preserved

public static ArrayList<ArrayList<HSSFCell>> newTogether(ArrayList<ArrayList<HSSFCell>> sheetData) {
ArrayList<ArrayList<HSSFCell>> temporary = new ArrayList<ArrayList<HSSFCell>>();
for(int i = 0; i < sheetData.size(); i++) {
ArrayList<HSSFCell> list = sheetData.get(i);
if (list.get(3).getCellType() == Cell.CELL_TYPE_NUMERIC) {
if(Integer.parseInt(list.get(3).getStringCellValue()) > 100) {
temporary.add(list);
sheetData.remove(i);
i--;
}
}
}
for(int i = 0; i < sheetData.size(); i++) {
ArrayList<HSSFCell> list = sheetData.get(i);
temporary.add(list);
}
return temporary;
}
What I am trying to do with my code is have the 2D ArrayList take out any numbers greater than 100 and put them in the beginning of the ArrayList, while preserving the order of the remaining elements. However, this code just returns an ArrayList in the original order, and if I add a println to either if, I get nothing. Could someone point out what it is I'm doing wrong?
Have you tried putting a println in front of the first if to check what getStringCellValue() returns?
btw. since Collections.sort is guaranteed to be stable according to the API documentation, you could use that. Should be faster than your way of doing it.
That could look like this
private static boolean biggerThan100(ArrayList<HSSFCell> list) {
return list.get(3).getCellType() == Cell.CELL_TYPE_NUMERIC &&
(Integer.parseInt(list.get(3).getStringCellValue()) > 100);
}
public static ArrayList<ArrayList<HSSFCell>> newTogether(ArrayList<ArrayList<HSSFCell>> sheetData) {
ArrayList<ArrayList<HSSFCell>> temp = new ArrayList<>(sheetData);
Collections.sort(temp, new Comparator<ArrayList<HSSFCell>>() {
public int compare(ArrayList<HSSFCell> a, ArrayList<HSSFCell> b) {
if(biggerThan100(a) && !biggerThan100(b)) return -1;
else if(biggerThan100(b) && !biggerThan100(a)) return 1;
else return 0;
}
});
return temp;
}

Array Processing

Array Processing
Hi! I need to create a boolean method that processes two strings and returns if one is a subset of another. Example
if AAC is a subset of AAABBCK return true/
I currently have
for (int i = 0; i < shorterArray.length; i++) {
for (int j = 0; j < longerArray.length; j++) {
if longerArray[j] == shorterArray[i] {
count++
}
}
if (count == shorterArray.length) {
return true
) else {
return fasle;
}
}
However this doesn't take into account the repetitions
return longerString.indexOf(shorterString) > -1;
Never mind, thanks to Joachim for correcting me on the definition of subset. Now I have to provide the correct answer.
public boolean isSubset(String subset, String superset)
{
boolean[] used = new boolean[superset.length()];
iLoop:
for (int i = 0; i < subset.length(); i++) {
for (int j = 0; j < superset.length(); j++) {
if (!used[j] && subset.charAt(i) == superset.charAt(j)) {
used[j] = true;
continue iLoop;
}
}
return false;
}
return true;
}
If you can use the built in methods within the String class :
String input="your input string with substring";
CharSequence findMe="substring";
boolean retval = input.contains(findMe);

Grouping Duplicates From a Sorted ArrayList into Another ArrayList

(Full disclosure: this is for some homework I can't seem to figure out.)
The task: Identify duplicates in a list and add them to another ArrayList to be printed out.
Specifications: I am NOT allowed to use any collection other than an ArrayList, so I can't use something like a Set. It seems like every answer on StackOverflow recommends use of a Set, which is why I decided to ask this question.
What I've attempted so far:
public static void deleteDuplicates(List<String> list)
{
int pointer = 1;
List<String> duplicates = new ArrayList<String>();
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i).equals(list.get(pointer))) {
duplicates.add(list.get(i));
if (pointer == 1) {
duplicates.add(list.get(pointer));
} else if ((pointer + 1) == list.size() - 1) {
duplicates.add(list.get(pointer));
}
pointer++;
} else {
display(duplicates);
duplicates = new ArrayList<String>();
pointer++;
}
}
}
The test data:
List<String> duplicated = new ArrayList<String>();
duplicated.add("3");
duplicated.add("3");
duplicated.add("30");
duplicated.add("46");
duplicated.add("46");
What's not working: When the size of the list is an odd number, the duplicates report correctly. When the size of the list is an even number, only the first two duplicates are reported.
The problem with your approach was the loop exits before it do the if-else check for last element. On the last iteration the if condition satisfies and it adds to duplicates but it wont enter the for loop again to goto the else part. So it does'nt get dispalyed. Try
public static void deleteDuplicates(List<String> list)
{
int pointer = 1;
List<String> duplicates = new ArrayList<String>();
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i).equals(list.get(pointer))) {
duplicates.add(list.get(i));
if (pointer == 1) {
duplicates.add(list.get(pointer));
} else if ((pointer + 1) == list.size() - 1) {
duplicates.add(list.get(pointer));
}
pointer++;
} else if(duplicates.size() > 0) {
display(duplicates);
duplicates.clear();
pointer++;
}
}
if(duplicates.size() > 0){
display(duplicates);
}
}
Although Syam S answer is right but this will work for unsorted array too:
public static void deleteDuplicates(List<String> list)
{
List<String> duplicates = new ArrayList<String>();
for (int j = 0; j < list.size() - 2; j++) {
int pointer = j;
for (int i = j+1; i < list.size() - 1; i++) {
if (list.get(i).equals(list.get(j))) {
duplicates.add(list.get(i));
duplicates.add(list.get(j));
}
if(duplicates.size() > 0){
System.out.println(duplicates);
duplicates.clear();
}
}
}
}
you can see the working version in Ideone
Try this:
Extending the ArrayList
1)
boolean result = false;
if(!contains(object))
result= super.add(object);
return result;
OR
2)
ArrayList<String> myList = new ArrayList<String>()
{
#Override
public boolean add(String object)
{
boolean present = false;
boolean result = false;
for(int i=0;i<size();i++)
{
if(object.equals(get(i)))
{
present = true;
break;
}
}
if(!present)
result= super.add(object);
return result;
}
};
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("1");
myList.add("1");
System.out.println(myList);

Categories

Resources