मेरे पास एक Map<Integer, Character> alphabetMap
है, जिसमें संख्या से लेकर वर्णमाला तक के लिंक हैं।
उदाहरण के लिए: [1: 'A', 2: 'B', ... , 26: 'Z']
मेरे पास एक रोटेट () विधि है, जो प्रविष्टियों को बदलते लिंक के साथ रखना चाहिए
पहली बार विधि का उपयोग करने के बाद मेरा नक्शा [1: 'Z', 2: 'A', 3: 'B', ... , 26: 'Y']
होना चाहिए
यहाँ मेरी वर्तमान प्राप्ति है:
public void rotate() {
final Map<Integer, Character> tempMap = new HashMap<>();
alphabetMap.forEach((key, value) -> tempMap.put(key == 26 ? 1 : key + 1, value));
alphabetMap = tempMap;
}
क्या मेरी प्रविष्टियों को तेज़ी से "घुमाने" के लिए कोई और तरीका/एल्गोरिदम है?
4 जवाब
"तेज़" रोटेशन के लिए मानचित्र को एक सूची और फिर विधि से बदला जा सकता है Collections.rotate
का उपयोग किया जा सकता है। फिर सूची तत्वों को सूचकांक द्वारा [0..25]
श्रेणी में पहुँचा जा सकता है।
या एक छोटा आवरण वर्ग लागू किया जा सकता है:
static class MyCharMap {
private List<Character> chars = IntStream
.rangeClosed('A', 'Z')
.mapToObj(c -> (char)c)
.collect(Collectors.toList());
public void rotate() {
Collections.rotate(chars, 1);
}
public Character get(Integer i) {
assert(1 <= i && i <= 26);
return chars.get(i - 1);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(4 * chars.size() + 2);
sb.append('{');
for (int i = 0, n = chars.size(); i < n; i++) {
if (i > 0) sb.append(", ");
sb.append(i + 1).append(':').append(chars.get(i));
}
sb.append('}');
return sb.toString();
}
}
परीक्षण:
MyCharMap chars = new MyCharMap();
chars.rotate();
chars.rotate();
System.out.println(chars);
System.out.println(chars.get(1));
आउटपुट:
{1:Y, 2:Z, 3:A, 4:B, 5:C, 6:D, 7:E, 8:F, 9:G, 10:H, 11:I, 12:J, 13:K, 14:L, 15:M, 16:N, 17:O, 18:P, 19:Q, 20:R, 21:S, 22:T, 23:U, 24:V, 25:W, 26:X}
Y
मानचित्र का उपयोग करते समय आपके दृष्टिकोण में कुछ भी गलत नहीं है। लेकिन चूंकि रोटेशन कुछ क्रम के सापेक्ष होना चाहिए और नक्शे अनियंत्रित हैं, आप एलेक्स रुडेंको द्वारा सुझाई गई सूची का उपयोग करना चाह सकते हैं। .
मानचित्रों का उपयोग करने का एक और विकल्प यहां दिया गया है। यह आपूर्ति किए गए मानचित्र के लिए किसी भी राशि (चिह्न के आधार पर) से बाएं या दाएं घुमाव की अनुमति देता है जिसमें अनुक्रमिक पूर्णांक कुंजियां 1 से शुरू होती हैं। यह remainder operator
का उपयोग करके आकार से अधिक की गणना के लिए भी समायोजित करता है। बाएँ या दाएँ घुमाव के लिए ऑफ़सेट की बस गणना की जाती है और नक्शा बदल दिया जाता है और बाद के प्रसंस्करण के लिए वापस कर दिया जाता है।
BiFunction<Map<Integer, Character>, Integer, Map<Integer, Character>> rotate =
(mp, cnt) -> {
int size = mp.values().size();
int count = cnt < 0 ? size + (cnt % size) - 1 :
cnt - 1;
return mp.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(
(e.getKey() + count) % size + 1,
e.getValue()))
.collect(Collectors.toMap(e -> e.getKey(),
e -> e.getValue()));
};
System.out.println(map); // original map - 10 elements
map = rotate.apply(map,1); // right one - starting at J
System.out.println(map);
map = rotate.apply(map,-2); // left two, skipping A, going to B
System.out.println(map);
map = rotate.apply(map, -21);// Essentially left one going to C
System.out.println(map);
map = rotate.apply(map, 22); // Essentially right two going to A
System.out.println(map);
प्रिंट
{1=A, 2=B, 3=C, 4=D, 5=E, 6=F, 7=G, 8=H, 9=I, 10=J}
{1=J, 2=A, 3=B, 4=C, 5=D, 6=E, 7=F, 8=G, 9=H, 10=I}
{1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H, 8=I, 9=J, 10=A}
{1=C, 2=D, 3=E, 4=F, 5=G, 6=H, 7=I, 8=J, 9=A, 10=B}
{1=A, 2=B, 3=C, 4=D, 5=E, 6=F, 7=G, 8=H, 9=I, 10=J}
लैम्ब्डा संस्करण को आसानी से एक नियमित विधि से बदला जा सकता है जो एक एकल घुमाव मान लेता है और एक निश्चित मानचित्र पर काम करता है।
जैसा कि @code-apprentice ने टिप्पणी में कहा है
चूँकि कुंजियाँ संख्यात्मक क्रम में हैं, मैं मानचित्र के बजाय एक सरणी या सूची का उपयोग करने का सुझाव देता हूँ।
यदि आप अभी भी एक नक्शा वापस करना चाहते हैं, तो आप Collections.rotate(...)
विधि अपेक्षित मानचित्र के पुनर्निर्माण के साथ संयोजन में।
BiFunction<List<?>, Integer, Map<Integer, ?>> rotate =
(list, distance) -> {
Function<List<?>, Map<Integer, ?>> setMap = (arrayList) -> IntStream.range(0, arrayList.size())
.boxed()
.collect(Collectors.toMap(arrayList::get, Function.identity()))
.entrySet()
.stream()
.peek(e -> e.setValue(e.getValue() + 1))
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
Collections.rotate(list, distance);
return setMap.apply(list);
};
System.out.println(rotate.apply(Arrays.asList('A', 'B', 'C', 'D'), 1)); // {1=D, 2=A, 3=B, 4=C}
System.out.println(rotate.apply(Arrays.asList("Peter", "James", "Sam", "Tiffany", "Mathew"), -3)); // {1=Tiffany, 2=Mathew, 3=Peter, 4=James, 5=Sam}
एलेक्स रुडेंको के उत्तर के आधार पर, आप एक कस्टम मानचित्र बना सकते हैं जो Collections.rotate(...) पीछे सीन।
कस्टम नक्शा:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
class MyMap {
private static int counter = 0;
private final Map<Integer, ?> initMap;
private final List<?> list;
private Map<Integer, ?> rotatedMap;
public MyMap(List<?> list) {
this.list = list;
this.initMap = setMap(this.list);
this.rotatedMap = cloneMap(this.initMap);
}
private Map<Integer, ?> setMap(List<?> list) {
return IntStream.range(0, list.size())
.boxed()
.collect(Collectors.toMap(list::get, Function.identity()))
.entrySet()
.stream()
.peek(e -> e.setValue(e.getValue() + 1))
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
}
private Map<Integer, ?> cloneMap(Map<Integer, ?> map) {
return map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
public Map<Integer, ?> get() {
counter = 0;
return rotatedMap;
}
public MyMap reset() {
counter = 0;
this.rotatedMap = cloneMap(this.initMap);
return this;
}
public MyMap rotate() {
return rotateMap(++counter);
}
public MyMap rotate(int distance) {
return rotateMap(distance);
}
private List<?> cloneList(List<?> list) {
return list.stream().map(e -> e).collect(Collectors.toList());
}
private MyMap rotateMap(int distance) {
List<?> list = cloneList(this.list);
Collections.rotate(list, distance);
this.rotatedMap = setMap(list);
return this;
}
public String toString() {
return rotatedMap.toString();
}
}
उदाहरण 1 (दो बार घुमाएँ, घुमाएँ रीसेट करें, दो बार घुमाएँ।):
// Rotate twice, Reset rotation, Rotate twice.
MyMap myCharMap1 = new MyMap(Arrays.asList('A', 'B', 'C', 'D'));
System.out.println(myCharMap1
.rotate(2)
.reset()
.rotate().rotate()
.get()); // {1=C, 2=D, 3=A, 4=B}
उदाहरण 2 (तीन बार घुमाएँ। एक स्ट्रिंग सूची को घुमा सकते हैं):
//Rotate thrice.
MyMap myMap = new MyMap(Arrays.asList("Peter", "James", "Sam", "Tiffany", "Mathew"));
System.out.println(myMap.rotate(3).get()); // {1=Sam, 2=Tiffany, 3=Mathew, 4=Peter, 5=James}
उदाहरण 3 (एक बार घुमाएँ। एक संख्यात्मक सूची को भी घुमा सकते हैं):
// Rotate once. Can rotate a numeric list as well.
MyMap myDigitMap3 = new MyMap(Arrays.asList(38, 56, 98, 160));
System.out.println(myDigitMap3.rotate(1).get()); // {1=160, 2=38, 3=56, 4=98}
उदाहरण 4 (नकारात्मक घुमाव स्वीकार कर सकते हैं):
//Can accept negative rotations.
MyMap myMap = new MyMap(Arrays.asList("Peter", "James", "Sam", "Tiffany", "Mathew"));
System.out.println(myMap.rotate(-3).get()); // {1=Tiffany, 2=Mathew, 3=Peter, 4=James, 5=Sam}
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।