2016-03-05 12 views
10

यह लगभग a cross post from Math SE है - जबकि मेरी समस्या का स्पष्टीकरण समान है, Math.SE पर मैं अपनी समस्या का गणितीय समाधान मांग रहा था।जावास्क्रिप्ट में एक अद्वितीय संख्या में वर्णों की एक अद्वितीय स्ट्रिंग को परिवर्तित करने का कोई आसान तरीका है?

मेरी समस्या यह है कि मैथ.एस. पर जो समाधान मिला, वह "बेस 35 में परिवर्तित हो गया" जो शायद एक बहुत अच्छा जवाब है, लेकिन मैं गणित के साथ वास्तव में भयानक हूं और समझ में नहीं आता कि मेरे समाधान में कैसे आवेदन करें कोड। मैंने a lesson on converting to different bases को देखने की कोशिश की, और यह मेरे लिए बहुत भ्रमित है। यहां तक ​​कि a question about converting numbers to bases in JavaScript को भी देखकर यह स्पष्ट नहीं हुआ कि मुझे क्या करना है इसके लिए मैं इसका उपयोग कैसे करूंगा।

क्या जावास्क्रिप्ट में इसे संभालने का कोई आसान तरीका है? यहां पूरा प्रश्न है:

मेरे पास असामान्य प्रोग्रामिंग समस्या है और इसके गणित पक्ष ने मुझे स्टंप कर दिया है।

मैंने सात पात्रों की एक अनूठी स्ट्रिंग जेनरेट की है जो प्रत्येक संभावनाओं से यादृच्छिक रूप से चुने गए हैं: ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789 उदाहरण के लिए A6HJ92B और मुझे इसे एक अद्वितीय संख्या मान में बदलने की आवश्यकता है। परिवर्तित होने पर, इस यादृच्छिक स्ट्रिंग के दो संस्करण नाम संख्या नहीं हो सकते हैं।

मैं मूल आईडी में अक्षरों को शामिल करने के बजाय सिर्फ एक संख्या उत्पन्न कर सकता हूं, लेकिन निश्चित रूप से इसका मतलब है कि मुझे अपनी स्ट्रिंग की लंबाई बढ़ाना है, और यह संभव है कि मेरे एप्लिकेशन का उपयोगकर्ता इस स्ट्रिंग को टाइप करना चाहे, क्योंकि यह किसी एप्लिकेशन में अपने "सत्र" की पहचान करता है, इसलिए मैं इसे छोटा रखना चाहता हूं।

तो मेरा विचार इस तरह की एक तालिका का निर्माण करना था:

A : 1, 
B : 2, 
C : 3, 
D : 4, 
E : 5, 
F : 6, 
G : 7, 
H : 8, 

... you get the idea ... 

5 : 31, 
6 : 32, 
7 : 33, 
8 : 34, 
9 : 35 

और फिर मैं संख्या के सभी जोड़ना होगा ...

A6HJ92B:

A : 1 
6 : 32 
H : 8 
J : 10 
9 : 35 
2 : 28 
B : 2 

1+32+8+10+35+28+2 = 116

... लेकिन मुझे एहसास हुआ कि यह एक दोषपूर्ण विचार है क्योंकि कई possib ले तार "टक्कर" या एक ही संख्या के बराबर होगा। मुझे एक अद्वितीय संख्या के बराबर करने के लिए प्रत्येक अद्वितीय स्ट्रिंग की आवश्यकता है।

तो अगर मैंने प्रत्येक चरित्र के मूल्य (1*32*8*10*35*28*2 = 5,017,600) को गुणा किया, तो भी मुझे लगता है कि वहां संभावित टकराव भी हो सकते हैं।

क्या इस तरह की गणना करने का कोई तरीका है टकराव को समाप्त करता है? अगर टकराव समाप्त नहीं किया जा सकता है, तो मैं उन्हें कम करने के लिए किस विधियों का उपयोग कर सकता हूं?

+0

bignumber.js के बारे में कैसे? https://mikemcl.github.io/bignumber।जेएस/ एक त्वरित पहेली बनाया: https://jsfiddle.net/7u0c2ddp/ –

+0

ऐसे रूपांतरण के असीमित तरीके हैं। सबसे आसान तरीका यह है: आपको पहले से ही स्मृति में अपनी स्ट्रिंग को शून्य और एक के रूप में प्रस्तुत करना होगा। बस इसे एक लंबी बाइनरी संख्या के रूप में देखें। –

+0

@IvanKuckir यह देखते हुए कि वर्णों का एक सीमित सेट है, तारों की संख्या सीमित है, और जेएस संख्याओं में स्मृति की सीमित मात्रा का उपयोग करके संग्रहीत किया जाता है, मुझे नहीं लगता कि रूपांतरण करने के अनंत तरीके हैं। वास्तव में उनमें से बहुत सारे हैं, हालांकि। – Oriol

उत्तर

16

मूल रूप से, आप एक injective परिवर्तन f : S → N, जहां S पात्रों A-Z1-9 साथ लंबाई 7 के जे एस तार का सेट है, और N सब जे एस संख्याओं के समूह है चाहता हूँ।

एक संभावित दृष्टिकोण यह विचार कर रहा है कि S में तार positional संख्याओं के एन्कोडिंग हैं, जैसा आपने प्रयास किया था।

हालांकि, इंजेक्शन (टक्कर से बचने के लिए) होने के लिए, आपको प्रत्येक चरित्र के मूल्य को आधार की स्थिति के आधार पर गुणा करना चाहिए।

उदाहरण के लिए, चरित्र की निम्न तालिका दिए गए महत्व देता

0 ⟶ 0 
1 ⟶ 1 
⋮  ⋮ 
9 ⟶ 9 
A ⟶ 10 
B ⟶ 11 
⋮  ⋮ 
Z ⟶ 35 

A6HJ92B10×36⁶ + 6×36⁵ + 17×36⁴ + 19×36³ + 9×36² + 2×36 + 11 बन जाएगा, कि, 22160072099 है।

आप parseInt और toString के साथ आसानी से रूपांतरण कर सकते हैं: आप मूल्यों की एक मनमाना तालिका उपयोग करना चाहते हैं

parseInt('A6HJ92B', 36); // 22160072099 
(22160072099).toString(36).toUpperCase(); // "A6HJ92B" 

, तो आप मैन्युअल परिवर्तनों कोड करने के लिए होगा।

ध्यान दें कि जेएस में, संख्या 64 बिट्स की डबल-परिशुद्धता फ्लोट हैं। इसका मतलब है कि एक सीमित परिशुद्धता है, और आप मनमाने ढंग से बड़े पूर्णांक स्टोर नहीं कर सकते हैं। यह इस अधिकतम

Number.MAX_SAFE_INTEGER; // 9007199254740991 
Number.MAX_SAFE_INTEGER.toString(36).toUpperCase(); // "2GOSA7PA2GV" 

से ठीक से काम नहीं करेगा, लेकिन आपके तारों में केवल 7 वर्ण हैं, इसलिए यह पर्याप्त होना चाहिए।

+0

वैसे, दोस्तों को शून्य छोड़कर चीजों को जटिल बनाने के लिए खेद है। कारण एक व्यावहारिक था: चूंकि उपयोगकर्ता (आपकी मां या पिता को सोचें) जो शायद कॉपी/पेस्ट फ़ंक्शन को नहीं जानते हैं, इस सत्र आईडी को किसी भी तरह से साझा करने का निर्णय ले सकते हैं, मैंने शून्य छोड़ दिया है, इसलिए यह भ्रमित नहीं होगा ओ। यह एक आवश्यकता नहीं है, लेकिन उपयोगकर्ता अनुभव के लिए अच्छा है। मेरे पास "प्रतिलिपि" बटन भी है, इसलिए यह वास्तव में महत्वपूर्ण नहीं है। –

+0

वाह यह बहुत आसान बनाता है। यह मेरे लिए काम किया। मुझे अभी एहसास नहीं हुआ कि 'parseInt' संख्याओं में रूपांतरण को संभालने में सक्षम होगा ... –

+0

@ विजिओयनरी इसके लायक होने के लिए, मुझे लगता है कि आसानी से भ्रमित पात्रों को छोड़ने का मामला एक सभ्य अलग-अलग अनुवर्ती प्रश्न बना देगा। (शायद वह जो पहले से मौजूद है।) असल में, आप ओई (या इसके विपरीत वाले) के साथ ज़ीरो को प्रतिस्थापित करने से पहले स्ट्रिंग को सामान्य कर सकते हैं, इसे किसी संख्या में परिवर्तित करने से पहले और वैकल्पिक रूप से, _from_ को कनवर्ट करने के बाद भी । –

6

अनिवार्य रूप से आप जो चाहते हैं वह जावा के hashcode के बराबर है। यह जावा में इस्तेमाल सूत्र है: String hashcode formula जहां n स्ट्रिंग की कुल लंबाई है, और रों [मैं] मैं स्ट्रिंग के वें चरित्र है। असल में आप क्या कर रहे हैं:

स्ट्रिंग में प्रत्येक वर्ण के लिए, स्ट्रिंग की कुल लंबाई और स्ट्रिंग माइनस 1 में वर्तमान वर्ण की अनुक्रमणिका के बीच अंतर की शक्ति को 31 तक बढ़ाएं।

4

आप स्थिति शक्ति से गुणा कर सकते हैं:

function StringAdder(obj){ 
    this.vals = obj; 
    this.add = function(str){ 
    var s = str.split(''), l = s.length, p = Math.pow(10, (l-1)), r = 0; 
    for(var i=0; i<l; i++){ 
     r += this.vals[s[i]]*p; p = p/10; 
    } 
    return r; 
    } 
} 
var vals = { 
    A: 1, 
    6: 32, 
    H: 8, 
    J: 10, 
    9: 35, 
    2: 28, 
    B: 2 
} 
var sa = new StringAdder(vals); 
console.log(sa.add('A6HJ92B')); console.log(sa.add('HJA6B29')); 
5

तुम बस समस्या के बारे में सही तरीके से सोच नहीं कर रहे हैं। चलो कुछ ऐसी चीज से शुरू करें जो आप अधिक परिचित हैं; दशमलव, या आधार 10 संख्याओं।

संख्या 7158 से बना है:

7 x 10^3 
+1 x 10^2 
+5 x 10^1 
+8 x 10^0 

आधार एक्स में संख्या का प्रतिनिधित्व करने के लिए आप एक्स

के साथ 10 की जगह तो अब सवाल बेस के बीच परिवर्तित करने के लिए कैसे हो जाता है। सबसे सरल समाधान एक्स द्वारा बार-बार विभाजित करना है - प्रत्येक बार शेष को एक्स एक्स में परिवर्तित करें और इसे तब तक नहीं छोड़ें जब तक कि कुछ भी नहीं छोड़ा जाता है, फिर अगले पुनरावृत्ति के लिए विभाजन के पूर्णांक भाग का उपयोग करें:

7158 /35 = 204 remainder 18 
204/35 = 5 remainder 29 
5/35 = 0 remainder 5 

तो आधार 35 में, दशमलव संख्या 7158 प्रतीकों आप के लिए [5] [29] [18]

चयन का प्रतिनिधित्व करती है आप 35 से प्रत्येक प्रभाग की आंशिक हिस्सा गुणा करके अपने आप को ऊपर के उदाहरण का प्रयास करें आपको कुछ परिणाम मिल सकते हैं जो पूर्णांक नहीं हैं - कंप्यूटर बाइनरी में काम करते हैं (और स्वचालित रूप से आधार रूपांतरण कर रहे हैं) और केवल अंकों की एक निश्चित संख्या के साथ काम करते हैं - Ie इस पर निर्भर करता है कि आप गणना कैसे करते हैं, आपको शेष को पूर्णांक के रूप में प्राप्त करने के लिए लगभग 0.00001 तक गोल करने की आवश्यकता हो सकती है।

+0

@cFreed मुझे लगता है, क्योंकि शीर्षक था "क्या अद्वितीय संख्या में अक्षरों की एक अद्वितीय स्ट्रिंग को परिवर्तित करने का एक आसान तरीका है जावास्क्रिप्ट में? " और SO प्रश्नों का बिंदु उन सभी लोगों के लिए उपयोगी होना चाहिए जिनके पास ऐसी ही समस्या हो सकती है, आमतौर पर इस समस्या को हल करने वाले उत्तर ठीक हैं। उम्मीद है कि मूल रूप से मैं अपने विशिष्ट चरित्र सेट के साथ समाधान को समझने के लिए इस और अन्य उत्तरों का उपयोग कर सकता हूं। लेकिन मैं इसे इतना विशिष्ट नहीं करना चाहता हूं कि प्रश्न और उत्तर केवल मेरे लिए उपयोगी हो जाएं। –

+0

@ विजयनियरी मैं सहमत हूं (ओरोल के उत्तर के तहत टिप्पणियां देखें)। यह है कि मैंने अन्य उत्तरों के तहत भी अपनी टिप्पणियां हटा दीं। – cFreed

संबंधित मुद्दे

 संबंधित मुद्दे