Checking if an integer permutation is cyclic in JavaMax heap in JavaPermutation of given stringPermutation...
Boss asked me to sign a resignation paper without a date on it along with my new contract
Was Opportunity's last message to Earth "My battery is low and it's getting dark"?
Why don't you get burned by the wood benches in a sauna?
Manager has noticed coworker's excessive breaks. Should I warn him?
Dot product with a constant
Can I combine Divination spells with Arcane Eye?
Question: "Are you hungry?" Answer: "I feel like eating."
How can guns be countered by melee combat without raw-ability or exceptional explanations?
What is formjacking?
What does it mean when an external ID field follows a DML Statement?
Is it common to refer to someone as "Prof. Dr. [LastName]"?
Why would you use 2 alternate layout buttons instead of 1, when only one can be selected at once
How to know if I am a 'Real Developer'
What is an explicit bijection in combinatorics?
What does @ mean in a hostname in DNS configuration?
How do I handle a blinded enemy which wants to attack someone it's sure is there?
Is it possible to detect 100% of SQLi with a simple regex?
Why do we interpret the accelerated expansion of the universe as the proof for the existence of dark energy?
When distributing a Linux kernel driver as source code, what's the difference between Proprietary and GPL license?
Spells that would be effective against a Modern Day army but would NOT destroy a fantasy one
How can I make my enemies feel real and make combat more engaging?
Have the UK Conservatives lost the working majority and if so, what does this mean?
Why is Bernie Sanders maximum accepted donation on actblue $5600?
3D buried view in Tikz
Checking if an integer permutation is cyclic in Java
Max heap in JavaPermutation of given stringPermutation algorithmRandom permutation of int[] and ArrayList<Integer>Heap's algorithm - integer permutationQuerying Facebook for details of a user's OAuth tokenImplementation of stackFinding Kth Permutation SequenceFinding the middle permutationCyclic Rotation
$begingroup$
A an integer permutation array[]
is said to be cyclic if and only if we can choose an arbitrary element at position i
, move it to the array[i]
's position, move the array[i]
's element to array[array[i]]
's position, and finally end up to the i
th position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:
package net.coderodde.math;
import java.util.Objects;
/**
* This class checks that a given permutation consists of a single cycle
* covering the entire sequence. The idea is that if the input array is
* {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
* On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
* only one permutation cycle.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 22, 2019)
*/
public class PermutationCyclicity {
private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
"array[%d] = %d, array.length = %d";
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
checkArrayHasLength(array);
checkArrayContentsWithinBounds(array);
checkArrayElements(array);
}
private void checkArrayHasLength(int[] array) {
Objects.requireNonNull(array, "The input array is null.");
if (array.length == 0) {
throw new IllegalArgumentException("The array has length zero.");
}
}
private void checkArrayContentsWithinBounds(int[] array) {
for (int i = 0; i < array.length; i++) {
int num = array[i];
if (num < 0 || num >= array.length) {
String exceptionMessage =
String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
i,
num,
array.length);
throw new IllegalArgumentException(exceptionMessage);
}
}
}
private void checkArrayElements(int[] array) {
int[] counts = new int[array.length];
for (int i : array) {
if (++counts[i] > 1) {
throw new IllegalArgumentException(
"The value " + i + " appears more than once.");
}
}
}
public static void main(String[] args) {
PermutationCyclicity pc = new PermutationCyclicity();
System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));
try {
pc.isCyclic(new int[] { 1, 0, 1 });
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try {
pc.isCyclic(new int[] { 1 });
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
}
}
Critique request
I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.
java algorithm array combinatorics
$endgroup$
add a comment |
$begingroup$
A an integer permutation array[]
is said to be cyclic if and only if we can choose an arbitrary element at position i
, move it to the array[i]
's position, move the array[i]
's element to array[array[i]]
's position, and finally end up to the i
th position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:
package net.coderodde.math;
import java.util.Objects;
/**
* This class checks that a given permutation consists of a single cycle
* covering the entire sequence. The idea is that if the input array is
* {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
* On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
* only one permutation cycle.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 22, 2019)
*/
public class PermutationCyclicity {
private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
"array[%d] = %d, array.length = %d";
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
checkArrayHasLength(array);
checkArrayContentsWithinBounds(array);
checkArrayElements(array);
}
private void checkArrayHasLength(int[] array) {
Objects.requireNonNull(array, "The input array is null.");
if (array.length == 0) {
throw new IllegalArgumentException("The array has length zero.");
}
}
private void checkArrayContentsWithinBounds(int[] array) {
for (int i = 0; i < array.length; i++) {
int num = array[i];
if (num < 0 || num >= array.length) {
String exceptionMessage =
String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
i,
num,
array.length);
throw new IllegalArgumentException(exceptionMessage);
}
}
}
private void checkArrayElements(int[] array) {
int[] counts = new int[array.length];
for (int i : array) {
if (++counts[i] > 1) {
throw new IllegalArgumentException(
"The value " + i + " appears more than once.");
}
}
}
public static void main(String[] args) {
PermutationCyclicity pc = new PermutationCyclicity();
System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));
try {
pc.isCyclic(new int[] { 1, 0, 1 });
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try {
pc.isCyclic(new int[] { 1 });
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
}
}
Critique request
I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.
java algorithm array combinatorics
$endgroup$
add a comment |
$begingroup$
A an integer permutation array[]
is said to be cyclic if and only if we can choose an arbitrary element at position i
, move it to the array[i]
's position, move the array[i]
's element to array[array[i]]
's position, and finally end up to the i
th position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:
package net.coderodde.math;
import java.util.Objects;
/**
* This class checks that a given permutation consists of a single cycle
* covering the entire sequence. The idea is that if the input array is
* {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
* On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
* only one permutation cycle.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 22, 2019)
*/
public class PermutationCyclicity {
private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
"array[%d] = %d, array.length = %d";
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
checkArrayHasLength(array);
checkArrayContentsWithinBounds(array);
checkArrayElements(array);
}
private void checkArrayHasLength(int[] array) {
Objects.requireNonNull(array, "The input array is null.");
if (array.length == 0) {
throw new IllegalArgumentException("The array has length zero.");
}
}
private void checkArrayContentsWithinBounds(int[] array) {
for (int i = 0; i < array.length; i++) {
int num = array[i];
if (num < 0 || num >= array.length) {
String exceptionMessage =
String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
i,
num,
array.length);
throw new IllegalArgumentException(exceptionMessage);
}
}
}
private void checkArrayElements(int[] array) {
int[] counts = new int[array.length];
for (int i : array) {
if (++counts[i] > 1) {
throw new IllegalArgumentException(
"The value " + i + " appears more than once.");
}
}
}
public static void main(String[] args) {
PermutationCyclicity pc = new PermutationCyclicity();
System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));
try {
pc.isCyclic(new int[] { 1, 0, 1 });
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try {
pc.isCyclic(new int[] { 1 });
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
}
}
Critique request
I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.
java algorithm array combinatorics
$endgroup$
A an integer permutation array[]
is said to be cyclic if and only if we can choose an arbitrary element at position i
, move it to the array[i]
's position, move the array[i]
's element to array[array[i]]
's position, and finally end up to the i
th position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:
package net.coderodde.math;
import java.util.Objects;
/**
* This class checks that a given permutation consists of a single cycle
* covering the entire sequence. The idea is that if the input array is
* {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
* On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
* only one permutation cycle.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 22, 2019)
*/
public class PermutationCyclicity {
private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
"array[%d] = %d, array.length = %d";
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
checkArrayHasLength(array);
checkArrayContentsWithinBounds(array);
checkArrayElements(array);
}
private void checkArrayHasLength(int[] array) {
Objects.requireNonNull(array, "The input array is null.");
if (array.length == 0) {
throw new IllegalArgumentException("The array has length zero.");
}
}
private void checkArrayContentsWithinBounds(int[] array) {
for (int i = 0; i < array.length; i++) {
int num = array[i];
if (num < 0 || num >= array.length) {
String exceptionMessage =
String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
i,
num,
array.length);
throw new IllegalArgumentException(exceptionMessage);
}
}
}
private void checkArrayElements(int[] array) {
int[] counts = new int[array.length];
for (int i : array) {
if (++counts[i] > 1) {
throw new IllegalArgumentException(
"The value " + i + " appears more than once.");
}
}
}
public static void main(String[] args) {
PermutationCyclicity pc = new PermutationCyclicity();
System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));
try {
pc.isCyclic(new int[] { 1, 0, 1 });
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try {
pc.isCyclic(new int[] { 1 });
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
}
}
Critique request
I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.
java algorithm array combinatorics
java algorithm array combinatorics
asked 2 hours ago
coderoddecoderodde
15.9k638127
15.9k638127
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
$begingroup$
Here
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
you determine the length of the orbit starting array[0]
. If you start at 0
instead then some array lookups are saved, and I find it easier to understand:
int nextNumber = array[0];
int visitedNumbers = 1;
while (nextNumber != 0) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
And with a do-while loop the initial array lookup can be made part of the loop:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (currentNumber != 0);
Further suggestions:
Checking for duplicate array elements is not necessary if you limit the number of iterations:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (visitedNumbers <= array.length && currentNumber != 0);
This saves one array traversal and the additional storage in checkArrayElements()
. The only downside is that calling the function with an invalid permutation now possibly returns false
instead of throwing an error.
Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.
$endgroup$
add a comment |
$begingroup$
For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength
, checkArrayContentsWithinBounds
and checkArrayElements
are private
, return void
and throw an IllegalArgumentException
.
Null Checking
The method checkArrayHasLength
checks for null
, but checkArrayElements
doesn`t.
So the method checkArrayElements
is dependent on checkArrayHasLength
in the method check
and you can't call them in an different order without to get your personalized exception message.
checkArrayHasLength(null); // personalized error message
checkArrayElements(null); // non personalized error message
Naming
After I looked into checkArrayHasLength
I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty
would be better.
The name checkArrayElements
is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce
would be better.
Type Embedded in Name
Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
Each method includes Array
, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..
New method names could be: checkIsNotEmpty
, checkElementsWithinBounds
and checkAllElementsOccurNotMoreThanOnce
.
Make it more Abstract
As already mention you have three methods that are private
, but they could be public
to.
Rename PermutationCyclicity
If we rename PermutationCyclicity
to Permutation
it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean
instead of void
and for that I would suggest to rename again all methods with an is
or are
prefix instead of check
.
As a Utility-Class
class Permutations {
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
if (isNotEmpty(array))
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds(array))
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty(int[] array) {* ... *}
public boolean areAllElementsWithinBounds(int[] array) {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}
}
As a Value-Object
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
check();
int nextNumber = values[values[0]];
int visitedNumbers = 1;
while (nextNumber != values[0]) {
nextNumber = values[nextNumber];
visitedNumbers++;
}
return visitedNumbers == values.length;
}
private void check() {
if (isNotEmpty())
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds())
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce())
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty() {* ... *}
public boolean areAllElementsWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}
}
Does it need to Throw?
I'm not if the method isCyclic
needs to throw an IllegalArgumentException
. From my feelings here a permutation can be cyclic or not - true
or false
. Additional if a client forgot to catch the IllegalArgumentException
, he will never get to know the reason.
If you want to make sure the client should get always the reason use not a RuntimeException
, because they don't have to be checked.
A other way would to use an algebraic data type. The Either
can be used to get a result or an error message.
Or just simply return false and the client has to find the reason:
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
if (isEmpty()
&& areAllElementsAreNotWithinBounds()
&& isOccurrenceOfAllElementsMoreThanOnce())
return false;
// ..
return visitedNumbers == values.length;
}
public boolean isEmpty() {* ... *}
public boolean areAllElementsAreNotWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}
}
public static void main(String[] args) {
Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});
if (permutation.isCyclic())
System.out.println("nice");
else {
if (!permutation.areAllElementsWithinBounds())
System.out.println("not all elements are in bound");
// ..
}
}
$endgroup$
$begingroup$
There seems to be some negation missing in your lastisCyclic()
function: It returns false if the array represents a valid permutation.
$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still saysif (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
add a comment |
$begingroup$
I would prefer checkArrayValidity
over the generic check
and PermutationCyclicityChecker
checker over PermutationCyclicity
as the class implements functionality, not state.
Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214013%2fchecking-if-an-integer-permutation-is-cyclic-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Here
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
you determine the length of the orbit starting array[0]
. If you start at 0
instead then some array lookups are saved, and I find it easier to understand:
int nextNumber = array[0];
int visitedNumbers = 1;
while (nextNumber != 0) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
And with a do-while loop the initial array lookup can be made part of the loop:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (currentNumber != 0);
Further suggestions:
Checking for duplicate array elements is not necessary if you limit the number of iterations:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (visitedNumbers <= array.length && currentNumber != 0);
This saves one array traversal and the additional storage in checkArrayElements()
. The only downside is that calling the function with an invalid permutation now possibly returns false
instead of throwing an error.
Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.
$endgroup$
add a comment |
$begingroup$
Here
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
you determine the length of the orbit starting array[0]
. If you start at 0
instead then some array lookups are saved, and I find it easier to understand:
int nextNumber = array[0];
int visitedNumbers = 1;
while (nextNumber != 0) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
And with a do-while loop the initial array lookup can be made part of the loop:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (currentNumber != 0);
Further suggestions:
Checking for duplicate array elements is not necessary if you limit the number of iterations:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (visitedNumbers <= array.length && currentNumber != 0);
This saves one array traversal and the additional storage in checkArrayElements()
. The only downside is that calling the function with an invalid permutation now possibly returns false
instead of throwing an error.
Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.
$endgroup$
add a comment |
$begingroup$
Here
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
you determine the length of the orbit starting array[0]
. If you start at 0
instead then some array lookups are saved, and I find it easier to understand:
int nextNumber = array[0];
int visitedNumbers = 1;
while (nextNumber != 0) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
And with a do-while loop the initial array lookup can be made part of the loop:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (currentNumber != 0);
Further suggestions:
Checking for duplicate array elements is not necessary if you limit the number of iterations:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (visitedNumbers <= array.length && currentNumber != 0);
This saves one array traversal and the additional storage in checkArrayElements()
. The only downside is that calling the function with an invalid permutation now possibly returns false
instead of throwing an error.
Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.
$endgroup$
Here
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
you determine the length of the orbit starting array[0]
. If you start at 0
instead then some array lookups are saved, and I find it easier to understand:
int nextNumber = array[0];
int visitedNumbers = 1;
while (nextNumber != 0) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
And with a do-while loop the initial array lookup can be made part of the loop:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (currentNumber != 0);
Further suggestions:
Checking for duplicate array elements is not necessary if you limit the number of iterations:
int currentNumber = 0;
int visitedNumbers = 0;
do {
currentNumber = array[currentNumber];
visitedNumbers++;
} while (visitedNumbers <= array.length && currentNumber != 0);
This saves one array traversal and the additional storage in checkArrayElements()
. The only downside is that calling the function with an invalid permutation now possibly returns false
instead of throwing an error.
Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.
edited 41 mins ago
answered 1 hour ago
Martin RMartin R
15.9k12364
15.9k12364
add a comment |
add a comment |
$begingroup$
For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength
, checkArrayContentsWithinBounds
and checkArrayElements
are private
, return void
and throw an IllegalArgumentException
.
Null Checking
The method checkArrayHasLength
checks for null
, but checkArrayElements
doesn`t.
So the method checkArrayElements
is dependent on checkArrayHasLength
in the method check
and you can't call them in an different order without to get your personalized exception message.
checkArrayHasLength(null); // personalized error message
checkArrayElements(null); // non personalized error message
Naming
After I looked into checkArrayHasLength
I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty
would be better.
The name checkArrayElements
is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce
would be better.
Type Embedded in Name
Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
Each method includes Array
, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..
New method names could be: checkIsNotEmpty
, checkElementsWithinBounds
and checkAllElementsOccurNotMoreThanOnce
.
Make it more Abstract
As already mention you have three methods that are private
, but they could be public
to.
Rename PermutationCyclicity
If we rename PermutationCyclicity
to Permutation
it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean
instead of void
and for that I would suggest to rename again all methods with an is
or are
prefix instead of check
.
As a Utility-Class
class Permutations {
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
if (isNotEmpty(array))
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds(array))
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty(int[] array) {* ... *}
public boolean areAllElementsWithinBounds(int[] array) {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}
}
As a Value-Object
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
check();
int nextNumber = values[values[0]];
int visitedNumbers = 1;
while (nextNumber != values[0]) {
nextNumber = values[nextNumber];
visitedNumbers++;
}
return visitedNumbers == values.length;
}
private void check() {
if (isNotEmpty())
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds())
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce())
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty() {* ... *}
public boolean areAllElementsWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}
}
Does it need to Throw?
I'm not if the method isCyclic
needs to throw an IllegalArgumentException
. From my feelings here a permutation can be cyclic or not - true
or false
. Additional if a client forgot to catch the IllegalArgumentException
, he will never get to know the reason.
If you want to make sure the client should get always the reason use not a RuntimeException
, because they don't have to be checked.
A other way would to use an algebraic data type. The Either
can be used to get a result or an error message.
Or just simply return false and the client has to find the reason:
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
if (isEmpty()
&& areAllElementsAreNotWithinBounds()
&& isOccurrenceOfAllElementsMoreThanOnce())
return false;
// ..
return visitedNumbers == values.length;
}
public boolean isEmpty() {* ... *}
public boolean areAllElementsAreNotWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}
}
public static void main(String[] args) {
Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});
if (permutation.isCyclic())
System.out.println("nice");
else {
if (!permutation.areAllElementsWithinBounds())
System.out.println("not all elements are in bound");
// ..
}
}
$endgroup$
$begingroup$
There seems to be some negation missing in your lastisCyclic()
function: It returns false if the array represents a valid permutation.
$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still saysif (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
add a comment |
$begingroup$
For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength
, checkArrayContentsWithinBounds
and checkArrayElements
are private
, return void
and throw an IllegalArgumentException
.
Null Checking
The method checkArrayHasLength
checks for null
, but checkArrayElements
doesn`t.
So the method checkArrayElements
is dependent on checkArrayHasLength
in the method check
and you can't call them in an different order without to get your personalized exception message.
checkArrayHasLength(null); // personalized error message
checkArrayElements(null); // non personalized error message
Naming
After I looked into checkArrayHasLength
I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty
would be better.
The name checkArrayElements
is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce
would be better.
Type Embedded in Name
Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
Each method includes Array
, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..
New method names could be: checkIsNotEmpty
, checkElementsWithinBounds
and checkAllElementsOccurNotMoreThanOnce
.
Make it more Abstract
As already mention you have three methods that are private
, but they could be public
to.
Rename PermutationCyclicity
If we rename PermutationCyclicity
to Permutation
it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean
instead of void
and for that I would suggest to rename again all methods with an is
or are
prefix instead of check
.
As a Utility-Class
class Permutations {
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
if (isNotEmpty(array))
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds(array))
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty(int[] array) {* ... *}
public boolean areAllElementsWithinBounds(int[] array) {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}
}
As a Value-Object
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
check();
int nextNumber = values[values[0]];
int visitedNumbers = 1;
while (nextNumber != values[0]) {
nextNumber = values[nextNumber];
visitedNumbers++;
}
return visitedNumbers == values.length;
}
private void check() {
if (isNotEmpty())
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds())
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce())
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty() {* ... *}
public boolean areAllElementsWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}
}
Does it need to Throw?
I'm not if the method isCyclic
needs to throw an IllegalArgumentException
. From my feelings here a permutation can be cyclic or not - true
or false
. Additional if a client forgot to catch the IllegalArgumentException
, he will never get to know the reason.
If you want to make sure the client should get always the reason use not a RuntimeException
, because they don't have to be checked.
A other way would to use an algebraic data type. The Either
can be used to get a result or an error message.
Or just simply return false and the client has to find the reason:
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
if (isEmpty()
&& areAllElementsAreNotWithinBounds()
&& isOccurrenceOfAllElementsMoreThanOnce())
return false;
// ..
return visitedNumbers == values.length;
}
public boolean isEmpty() {* ... *}
public boolean areAllElementsAreNotWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}
}
public static void main(String[] args) {
Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});
if (permutation.isCyclic())
System.out.println("nice");
else {
if (!permutation.areAllElementsWithinBounds())
System.out.println("not all elements are in bound");
// ..
}
}
$endgroup$
$begingroup$
There seems to be some negation missing in your lastisCyclic()
function: It returns false if the array represents a valid permutation.
$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still saysif (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
add a comment |
$begingroup$
For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength
, checkArrayContentsWithinBounds
and checkArrayElements
are private
, return void
and throw an IllegalArgumentException
.
Null Checking
The method checkArrayHasLength
checks for null
, but checkArrayElements
doesn`t.
So the method checkArrayElements
is dependent on checkArrayHasLength
in the method check
and you can't call them in an different order without to get your personalized exception message.
checkArrayHasLength(null); // personalized error message
checkArrayElements(null); // non personalized error message
Naming
After I looked into checkArrayHasLength
I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty
would be better.
The name checkArrayElements
is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce
would be better.
Type Embedded in Name
Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
Each method includes Array
, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..
New method names could be: checkIsNotEmpty
, checkElementsWithinBounds
and checkAllElementsOccurNotMoreThanOnce
.
Make it more Abstract
As already mention you have three methods that are private
, but they could be public
to.
Rename PermutationCyclicity
If we rename PermutationCyclicity
to Permutation
it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean
instead of void
and for that I would suggest to rename again all methods with an is
or are
prefix instead of check
.
As a Utility-Class
class Permutations {
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
if (isNotEmpty(array))
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds(array))
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty(int[] array) {* ... *}
public boolean areAllElementsWithinBounds(int[] array) {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}
}
As a Value-Object
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
check();
int nextNumber = values[values[0]];
int visitedNumbers = 1;
while (nextNumber != values[0]) {
nextNumber = values[nextNumber];
visitedNumbers++;
}
return visitedNumbers == values.length;
}
private void check() {
if (isNotEmpty())
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds())
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce())
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty() {* ... *}
public boolean areAllElementsWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}
}
Does it need to Throw?
I'm not if the method isCyclic
needs to throw an IllegalArgumentException
. From my feelings here a permutation can be cyclic or not - true
or false
. Additional if a client forgot to catch the IllegalArgumentException
, he will never get to know the reason.
If you want to make sure the client should get always the reason use not a RuntimeException
, because they don't have to be checked.
A other way would to use an algebraic data type. The Either
can be used to get a result or an error message.
Or just simply return false and the client has to find the reason:
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
if (isEmpty()
&& areAllElementsAreNotWithinBounds()
&& isOccurrenceOfAllElementsMoreThanOnce())
return false;
// ..
return visitedNumbers == values.length;
}
public boolean isEmpty() {* ... *}
public boolean areAllElementsAreNotWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}
}
public static void main(String[] args) {
Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});
if (permutation.isCyclic())
System.out.println("nice");
else {
if (!permutation.areAllElementsWithinBounds())
System.out.println("not all elements are in bound");
// ..
}
}
$endgroup$
For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength
, checkArrayContentsWithinBounds
and checkArrayElements
are private
, return void
and throw an IllegalArgumentException
.
Null Checking
The method checkArrayHasLength
checks for null
, but checkArrayElements
doesn`t.
So the method checkArrayElements
is dependent on checkArrayHasLength
in the method check
and you can't call them in an different order without to get your personalized exception message.
checkArrayHasLength(null); // personalized error message
checkArrayElements(null); // non personalized error message
Naming
After I looked into checkArrayHasLength
I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty
would be better.
The name checkArrayElements
is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce
would be better.
Type Embedded in Name
Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.
Each method includes Array
, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..
New method names could be: checkIsNotEmpty
, checkElementsWithinBounds
and checkAllElementsOccurNotMoreThanOnce
.
Make it more Abstract
As already mention you have three methods that are private
, but they could be public
to.
Rename PermutationCyclicity
If we rename PermutationCyclicity
to Permutation
it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean
instead of void
and for that I would suggest to rename again all methods with an is
or are
prefix instead of check
.
As a Utility-Class
class Permutations {
public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;
while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}
return visitedNumbers == array.length;
}
private void check(int[] array) {
if (isNotEmpty(array))
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds(array))
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty(int[] array) {* ... *}
public boolean areAllElementsWithinBounds(int[] array) {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}
}
As a Value-Object
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
check();
int nextNumber = values[values[0]];
int visitedNumbers = 1;
while (nextNumber != values[0]) {
nextNumber = values[nextNumber];
visitedNumbers++;
}
return visitedNumbers == values.length;
}
private void check() {
if (isNotEmpty())
throw new IllegalArgumentException("The array has length zero.");
if (areAllElementsWithinBounds())
throw new IllegalArgumentException("Argument contains elements that are not in the bound");
if (isOccurrenceOfAllElementsNotMoreThanOnce())
throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
}
public boolean isNotEmpty() {* ... *}
public boolean areAllElementsWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}
}
Does it need to Throw?
I'm not if the method isCyclic
needs to throw an IllegalArgumentException
. From my feelings here a permutation can be cyclic or not - true
or false
. Additional if a client forgot to catch the IllegalArgumentException
, he will never get to know the reason.
If you want to make sure the client should get always the reason use not a RuntimeException
, because they don't have to be checked.
A other way would to use an algebraic data type. The Either
can be used to get a result or an error message.
Or just simply return false and the client has to find the reason:
class Permutation {
private int[] values;
public Permutation(int[] values) {
this.values = Objects.requireNonNull(values, "The argument is null.");
}
public boolean isCyclic() {
if (isEmpty()
&& areAllElementsAreNotWithinBounds()
&& isOccurrenceOfAllElementsMoreThanOnce())
return false;
// ..
return visitedNumbers == values.length;
}
public boolean isEmpty() {* ... *}
public boolean areAllElementsAreNotWithinBounds() {* ... *}
public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}
}
public static void main(String[] args) {
Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});
if (permutation.isCyclic())
System.out.println("nice");
else {
if (!permutation.areAllElementsWithinBounds())
System.out.println("not all elements are in bound");
// ..
}
}
edited 1 min ago
answered 13 mins ago
RomanRoman
671214
671214
$begingroup$
There seems to be some negation missing in your lastisCyclic()
function: It returns false if the array represents a valid permutation.
$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still saysif (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
add a comment |
$begingroup$
There seems to be some negation missing in your lastisCyclic()
function: It returns false if the array represents a valid permutation.
$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still saysif (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
$begingroup$
There seems to be some negation missing in your last
isCyclic()
function: It returns false if the array represents a valid permutation.$endgroup$
– Martin R
7 mins ago
$begingroup$
There seems to be some negation missing in your last
isCyclic()
function: It returns false if the array represents a valid permutation.$endgroup$
– Martin R
7 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
@MartinR psst.. Already fixed it. Thanks
$endgroup$
– Roman
5 mins ago
$begingroup$
Check again: Unless I am mistaken, it still says
if (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
$begingroup$
Check again: Unless I am mistaken, it still says
if (array is valid) { return false }
$endgroup$
– Martin R
4 mins ago
add a comment |
$begingroup$
I would prefer checkArrayValidity
over the generic check
and PermutationCyclicityChecker
checker over PermutationCyclicity
as the class implements functionality, not state.
Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).
$endgroup$
add a comment |
$begingroup$
I would prefer checkArrayValidity
over the generic check
and PermutationCyclicityChecker
checker over PermutationCyclicity
as the class implements functionality, not state.
Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).
$endgroup$
add a comment |
$begingroup$
I would prefer checkArrayValidity
over the generic check
and PermutationCyclicityChecker
checker over PermutationCyclicity
as the class implements functionality, not state.
Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).
$endgroup$
I would prefer checkArrayValidity
over the generic check
and PermutationCyclicityChecker
checker over PermutationCyclicity
as the class implements functionality, not state.
Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).
answered 21 mins ago
TorbenPutkonenTorbenPutkonen
21117
21117
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214013%2fchecking-if-an-integer-permutation-is-cyclic-in-java%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown