time complexity for comparing two strings - javascript

How is the running time of the ff function o(nlogn)?
function isPermutation(a, b) {
if (a.length !== b.length) {
return false;
}
return a.split("").sort().join() === b.split("").sort().join();
}
aren't you checking the length of both strings, or is it dependent on the implementation of sort?

According to definition of Permutation, a String is permutate of another String if and only if all chars in the first String are also in the second String.
Example: "answer" is permutate of "awerns".
So to write an algorithm that checks if one string is permutate of another string all you have to do is:
Check if length of the two strings is same, return false if they are not same.
For each letter in String one check if it also exists in String two.
The above algorithm's running time will be but you can use sorting to solve same problem:
Check if length of two strings is same, return false if they are not same.
Sort the two strings
Each char in the Strings sequentially, like stringOne[i] == stringTwo[i]
So in this one if you use good sorting algorithm like Quick Sort or Merge Sort the overall running time will be

Related

When comparing strings, does JavaScript start by comparing their length?

I would like to know if, when comparing two (potentially massive) strings, JavaScript internally starts by comparing their length before looping over the characters.
If not, would that mean doing something along the lines of
if (string1.length !== string2.length || string1 !== string2)
// do something if data changed
should lead to a gain of time, right ? (I am assuming the read-only length property of a string is computed when the string is set, and not when asked; Not sure if that's actually the case)
For context, I am dealing with massive strings as I am lazily JSON.stringifying arrays of objects received from some API (comparing the latest element only would probably be better but this question is more out of curiosity than anything, please only mind that the strings I would compare would be humongous ^^)
Relevant references ?
https://javascript.info/comparison
Comparing large strings in JavaScript with a hash
Edit
Thank you #RobG in the comment for linking me to ECMA-262's SameValueNonNumber.
In the step definition, step 5 is
SameValueNonNumber ( x, y )
5.If Type(x) is String, then
If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
And I think that answers the question

Using sort() to get numbers in descending order

I'm trying to complete this kata. Trying to figure it out, I've seen this thread but I think I'm doing it as it says in there.
What am I doing wrong? Why doesn't it sort the numbers in descending order?
This is my code so far:
function descendingOrder(n){
let newN = n.toString().split(' ').sort(function(a,b){return b-a}).join();
return parseInt(newN);
}
Test Passed: Value == 0
Test Passed: Value == 1
Expected: 987654321, instead got: 123456789
Thanks in advance
You need to split the string with an empty string '' to get single digits and join it with an empty string.
Splitting with a character which is not part of the string results in an array with a single value. A later joined array returns this single element. That is why you get the same value as result as the input.
Array#join without a specified separator, returns a comma separated string with the values.
let newN = n.toString().split('').sort(function (a, b) { return b - a; }).join('');
At the end, you could take an unary plus +, like
return +newN;
for getting an numerical value.
BTW, with the use of parseInt, you may specify a radix, because strings with leading zero may be converted to an octal number.
Here is an explained answer
function descendingOrder(n) {
let result = n
.toString() // convert numbers to string
.split('') // split each string char in to an array of chars
.sort((a, b) => b - a) // sort that array descending
.join('') // regroup all items in that array into 1 string
return parseInt(result) // turn the group of strings into an array
}
function descendingOrder(n){
return +('' + n).split('').sort().reverse().join('');
}
Like the other answers have already stated you will need to call split with an empty string to properly create an array containing each character.
Also, when I tested join() I noticed commas in the output (chrome 65). I added a replace function to strip the commas, which passed the test.
function descendingOrder(n){
let newN = n.toString().split('').sort(function(a,b){return b-a}).join().replace(/,/g,'');
return parseInt(newN);
}

Can someone explain the difference between these JS functions one with callback and other no with callback

To sort an array we can do:
1.
var values = [0,3,2,5,7,4,8];
console.log(values.sort());
2.
var values = [0,3,2,5,7,4,8];
values.sort(function(v1,v2){
return v1-v2;
});
console.log(values);
Both give the same output, but which one is faster or better?
They're not equivalent unless all the numbers in the array have the same number of digits. The default comparison function for sort() compares the array elements as strings, not as numbers, and the string "10" is less than "2". You can see the difference if you add a 2-digit number to the array.
var values = [0,3,2,5,7,4,8, 10];
console.log(JSON.stringify(values.sort()));
console.log(JSON.stringify(values.sort(function(v1,v2){
return v1-v2;
})));
Comparing their performance seems pointless, since they do different things, and it's likely that the first form is simply wrong.
So the first .sort() call uses the default comparer, which can be found referenced in this documentation.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
"If compareFunction is not supplied, elements are sorted by converting them to strings and comparing strings in Unicode code point order."
The second sort uses your custom comparer, which does an integer comparison instead of string comparison.
The second should be faster since it doesn't need to do the string conversion on top of the comparisons.

Explain this sorting in JavaScript

var a = ['a100', 'a1', 'a10'];
a.sort();
This logs: ["a1", "a10", "a100"]
var a = ['f_a100_', 'f_a1_', 'f_a10_'];
a.sort();
But this logs: ["f_a100_", "f_a10_", "f_a1_"]
Can you please advise me why is that?
Array.sort sorts value by converting the item to string and then doing a lexicographical sort.
Now, by lexicographical sorting all that they mean is that they compare the string characters one by one till a non matching character is found. The position of the non matching character in the character-set (where letters are ordered alphabetically) decides the rank of the string.
f_a100_
^
f_a1_
^
f_a10_
^
See the first non matching character. Here _ is greater than 0 (check their ascii codes) so f_a100_ and f_a10_ comes above f_a1_. Now between those two we go to the next character
f_a100_
^
f_a10_
^
Here, applying the same logic f_a100_ comes first. So the final order is ["f_a100_", "f_a10_", "f_a1_"]
This sorting order would seem logical for simple strings. But for certain other cases like yours it works weirdly because of the way the charsets are arranged. To get a desired behaviour you should write your own compare function that strips out the number part and return a positive, negative or 0 value as shown in the example.
Javascript sorting is string based:
var a = ['a100', 'a1', 'a10'];
a.sort();
Will return:
["a1", "a10", "a100"]
Because of string comparison: "a1" < "a10" < "a100". In the other example, "f_a100_" < "f_a10_" because "0" < "_", and "f_a10_" < "f_a1_" for the same reason.
Indeed this:
[15, 13, 8].sort();
will return:
[13, 15, 8]
This is something a little weird, but that's how it's designed. If you want to change the ordering criteria you can pass a function as a parameter. E.g. (From here)
var points = [40,100,1,5,25,10];
points.sort(function(a,b){return a-b});
The javascript sort function does sorting alphanumerically not arithmetically so you get the results such. See this question that is almost same with yours Array Sort in JS
In the first case "a1" < "a10" because when comparing two strings the "a1" portion matches but then it decides that "a1" has a shorter length.
But in the second case "f_a1_" > "f_a10_", because when comparing these two the "f_a1" portion matches and then "_" is compared to "0". And '_' > '0' because they are compared by their ascii value.
Array.sort uses string sorting (even if the array is a list of numbers).
The sorting you're looking for is known as natural order sorting. In this sorting numbers are treated as numbers, 100 comes after 10, 2 comes before 10 etc.
JavaScript does not natively have a natsrt. I have written my own implementation but it's quite involved. Here is a reference implementation: http://phpjs.org/functions/strnatcmp/
If you just need to sort strings of the form f_a[0-9]+_ you can write a regular expression to extract the number part.

How do you sort or compare Strings in JavaScript based on a certain locale?

I know there is a function called String.prototype.localeCompare which you can use, and you can send in as the second argument a list of locales.
string.localeCompare(compareString [, locales [, options]])
But if you look at the browser compatibility table, only Chrome supports it.
How do you sort or compare Strings in JavaScript based on a certain locale?
How does all the big websites do this, like ebay or amazon? They must have some kind of String sorting in the front-end.. right?
May be you need sorting, not compare?
Javascript array sort method sort strings on its Unicode(not ASCII) codes. You can sort array of strings to get it in alphabetical order.
['Собака', 'Кошка'].sort() will sort array to ["Кошка", "Собака"] which is right in Ru_ru locale.
You can add compare function like this:
['Собака', 'Кошка', 'Свекла'].sort(function(a, b) {
return a[1] > b[1]?1:-1;
})
Javascript will compare strings by Unicode character by character. In my example compare is inside a[1] > b[1] on native low-level code. Return -1 or 1 needs for sort function to replace array elements.

Categories