Sorting array items by frequency value - arrays

is there a good way or algorithm to sort an array by the value of a frequency in each item? Let's say I have this array:
[3, 3, 3, 5, 6, 12, 5, 5, 6]. I want the output to be [3, 5, 6, 12]. I was thinking about something like insertionsort but I belive that there could be an easier way.

Well, you definetly need the count for each element, which is O(n). Then you can make a unique list from it (let's say it has m elements), and sort it according to the frequency with any sorting algo, you like. It will be O(n+mlog(m)).
For example in python:
from collections import Counter
myList = ['a', 'b', 'b', 'a', 'b', 'c']
myCounter = Counter(myList)
myUniqueList = list(myCounter)
sorted(myUniqueList, key=lambda e: myCounter[e])
Editted according to Paddy3118 's comment

First you count them
std::unordered_map<int, int> dict;
for(auto &val : array)
dict[val]++; // O(N)
Then you sort them
std::vector vec(dict.begin(), dict.end());
std::sort(vec.begin(), vec.end(), [](auto a, auto b) { return a.second > b.second }); // O(M lg M), requires C++14 to use auto

Related

Check if SOME array values are equal

I'm looking for a way to check if some values of an array are equal, here is an example :
[1, 2, 3, 4] //False
[1, 1, 2, 3] //True
['a', 'a', 'a', 'a', ] // True
I already found this method, that returns 'true' if EVERY array values are equal but it's not what I want :
console.log([1,1,1,1].every( (val, i, arr) => val === arr[0] ))
Thanks
If the collection obtained by keeping only the distinct elements is smaller than the original collection, then there were duplicate elements:
val seq = Seq(1, 1, 2, 3)
seq.distinct.size < seq.size
//=> true
This typically runs in O(n) time and O(n) space. However, you should be able to also make it short-circuiting so that it aborts as soon as it finds a duplicate element:
require 'set'
ary = [1, 2, 3, 1]
!ary.each_with_object(Set[]) {|el, set| break if set.include?(el); set << el }
#=> true

Reduce array to tuple of first and last element?

I have an array that I would like to first sort, then return the first and last element of the sorted array. I thought I can use reduce, but what if I don't have an initial value?
Here is the array I'm trying to work with:
let myNumbers = [4, 9, 6, 2, 3]
How can map this to the first and last of the sorted array to this?:
(2, 9)
Method 1: min()/max()
This is the easiest way:
let input = [4, 9, 6, 2, 3]
let output = (input.min(), input.max())
print(output) //(Optional(2), Optional(9))
If you're certain that the array isn't empty, you can safely force unwrap the optionals:
let input = [4, 9, 6, 2, 3]
let output = (input.min()!, input.max()!) // (2, 9)
This is approach does 2 iterations over the array. It's O(N). Unless a sorted list is required elsewhere, sorting then taking the first/last would be worse, as it would be O(N * log_2(N)).
Method 2: reduce()
If you insist on using reduce, you can do it like this:
let input = [4, 9, 6, 2, 3]
let output = input.reduce((min: Int.max, max: Int.min)){
(min($0.min, $1), max($0.max , $1))
} //(2, 9)
Each reduce iteration sets the accumulator to the new min (the smaller of the old min and current element), and the new max (the larger of the old max and the current).
The initial values of the accumulator are set such that:
Any element in the array compares as smaller than the accumulator's min
Any element in the array compares as larger than the accumulator's max
You don't need an initialValue for reduce, it's optional.
var foo = [1, 40, 20, -20, 50];
var reducer = function(prev, curr, i, arr){return [prev[0] <= curr ? prev[0] : curr, prev[1] >= curr ? prev[1] : curr]};
var baz = foo.reduce(reducer); // [-20, 50]
Or maybe like this:
var foo = [1, 40, 20, -20, 50];
var reducer = function(prev, curr, i, arr){return {min: prev.min <= curr ? prev.min : curr, max: prev.max >= curr ? prev.max : curr}};
var baz = foo.reduce(reducer); // {min: -20, max: 50}
Edit: Just noticed this is for swift and not javascript, whoops lol. I must have been surfing the wrong SO category. I think the principle would be the same in swift except you probably do need to provide some kind of initial value.

How is the final array constructed in this Ruby quicksort implementation?

I'm learning some soring algorithms in Ruby, and learned this recursive implementation of quicksort:
class Array
def quicksort
return [] if empty?
pivot = delete_at(rand(size))
left, right = partition(&pivot.method(:>))
return *left.quicksort, pivot, *right.quicksort
end
end
array = [5,3,2,18,1,6,4,7,5,9,0]
p array
#=> [5, 3, 2, 18, 1, 6, 4, 7, 5, 9, 0]
p array.quicksort
#=> [0, 1, 2, 3, 4, 5, 5, 6, 7, 9, 18]
I think I understand basically what's happening here. Do I have this right?
Chose an arbitrary pivot, store the number and delete that index from the array. Then partition the array, putting numbers > pivot in an array left, and the numbers < pivot in right. Return pivot and call quicksort recursively on left and right arrays if they have anything in them.
What I don't understand is how the final array is constructed; I don't see where the returned numbers are assigned the appropriate index. Does it happen when pivot is returned? How does it end up in the right index?
I think some of my confusion is coming from a lack of understanding about recursion.
Thanks in advance for any help.
When you call return with a list of values, Ruby turns the list into an array and returns the array.
def return_array
return 1, 2
end
return_array
#=> [1, 2]
This can be used in conjunction with the Array to Arguments Conversion, which turns an array into a list of elements with the splat operator '*'.
a = [1, 2]
def add(c, d)
c + d
end
add(*a)
#=> 3
The return statements in the quicksort method does this trick, it returns a list with
The splat quick sort result of the left, which are all the elements that's less than the pivot (pivot.method(:>).call(elem), i.e., pivot > elem)
The pivot
The splat quick sort result of the right, which are all the elements that's greater or equal than the pivot (! (pivot > elem))
And Ruby turns them into an array and return that array.

Splitting an Array into Sub-Arrays in Swift [duplicate]

This question already has answers here:
In Swift, an efficient function that separates an array into 2 arrays based on a predicate
(7 answers)
Closed 6 months ago.
Problem
Given an array of values how can I split it into sub-arrays made of elements that are equal?
Example
Given this array
let numbers = [1, 1, 1, 3, 3, 4]
I want this output
[[1,1,1], [3, 3], [4]]
What I am NOT looking for
A possible way of solving this would be creating some sort of index to indicate the occurrences of each element like this.
let indexes = [1:3, 3:2, 4:1]
And finally use the index to rebuild the output array.
let subsequences = indexes.sort { $0.0.0 < $0.1.0 }.reduce([Int]()) { (res, elm) -> [Int] in
return res + [Int](count: elm.1, repeatedValue: elm.0)
}
However with this solution I am losing the original values. Of course in this case it's not a big problem (an Int value is still and Inteven if recreated) but I would like to apply this solution to more complex data structures like this
struct Starship: Equatable {
let name: String
let warpSpeed: Int
}
func ==(left:Starship, right:Starship) -> Bool {
return left.warpSpeed == right.warpSpeed
}
Final considerations
The function I am looking for would be some kind of reverse of flatten(), infact
let subsequences: [[Int]] = [[1,1,1], [3, 3], [4]]
print(Array(subsequences.flatten())) // [1, 1, 1, 3, 3, 4]
I hope I made myself clear, let me know should you need further details.
// extract unique numbers using a set, then
// map sub-arrays of the original arrays with a filter on each distinct number
let numbers = [1, 1, 1, 3, 3, 4]
let numberGroups = Set(numbers).map{ value in return numbers.filter{$0==value} }
print(numberGroups)
[EDIT] changed to use Set Initializer as suggested by Hamish
[EDIT2] Swift 4 added an initializer to Dictionary that will do this more efficiently:
let numberGroups = Array(Dictionary(grouping:numbers){$0}.values)
For a list of objects to be grouped by one of their properties:
let objectGroups = Array(Dictionary(grouping:objects){$0.property}.values)
If you could use CocoaPods/Carthage/Swift Package Manager/etc. you could use packages like oisdk/SwiftSequence which provides the group() method:
numbers.lazy.group()
// should return a sequence that generates [1, 1, 1], [3, 3], [4].
or UsrNameu1/TraverSwift which provides groupBy:
groupBy(SequenceOf(numbers), ==)
If you don't want to add external dependencies, you could always write an algorithm like:
func group<S: SequenceType where S.Generator.Element: Equatable>(seq: S) -> [[S.Generator.Element]] {
var result: [[S.Generator.Element]] = []
var current: [S.Generator.Element] = []
for element in seq {
if current.isEmpty || element == current[0] {
current.append(element)
} else {
result.append(current)
current = [element]
}
}
result.append(current)
return result
}
group(numbers)
// returns [[1, 1, 1], [3, 3], [4]].
Let's assume that you have an unsorted array of items. You will need to sort the initial array then you will have something like this:
[1, 1, 1, 3, 3, 4]
After that you will initialize two arrays: one for storing arrays and another one to use it as a current array.
Loop through the initial array and:
if the current value isn't different from the last one, push it to the current array
otherwise push the current array to the first one then empty the current array.
Hope it helps!
Worth mentioning, using Swift Algorithms this is now a one-liner:
import Algorithms
let numbers = [1, 1, 1, 3, 3, 4]
let chunks: [[Int]] = numbers.chunked(by: ==).map { .init($0) }
print(chunks) // [[1, 1, 1], [3, 3], [4]]

Sort array in Scala partially

How can I sort a region in an array in Scala?
I have an array, say var DivA = new Array[Int](100005).
I filled the elements in DivA up to some position which is less than 100005.
For example my array looks like Diva = {1,2,10,5,15,20}.
In C++ we have sort(DivA, DivA + N), but how can we sort arrays in Scala up to a certain index?
I tried Sorting.quickSort(DivA), but I don't know how to define the index up to which I want to sort the array, so that the statement above sorts the array, and the array looks like DivA={0,0,0,0,0}?
var Diva=new Array[Int](10000);
for(j<-15 to 0 by -1){
DivA(posA)=j;
posA=posA+1;
}
Sorting.quickSort(DivA);
for(j<-0 to posA-1)
{
print(DivA(j));
print(" ");
}
If you want to sort a region in an array, you can use the sort method in java.util.Arrays:
java.util.Arrays.sort(DivA, 0, 15)
this method offers fromIndex and toIndex. Note that this method sorts in place. That's probably OK in your case, as the style you apply seems to be "imperative".
If performance matters, arrays will probably be faster than other collections. Other reasons for using arrays might be memory consumption or interoperability.
Otherwise you can probably design your data structures/algorithm in a different (more "functional") way by using idiomatic Scala collections.
You can use sorted or sortBy, depending on your needs. In case of simple Array[Int], sorted should be enough:
val arr = Array.iterate(15, 15)(_ - 1)
arr: Array[Int] = Array(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
val sortedArray = arr.sorted
sortedArray: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
You can provide your own Ordering typeclass if you want some other kind of order.
You can find it in the documentation.
Although, as was noted in other answer, you should prefer immutable Vector unless you have good reason to switch to Array.
sorted() method is common for all collections, and Arrays in Scala are implicitly converted to a collection.
So you can call sorted on Array[Int], eg:
scala> val p = (10 to 1 by -1).toArray
p: Array[Int] = Array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
scala> p.sorted
res5: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
First, if you are programming in Scala, you should think about Vector or List because those are immutable which is prefferd way of programming in Scala...
And for Vector and List there is sorted() function which sorts an array

Resources