హాయ్! ఈ రోజు మనం ఏదైనా ప్రోగ్రామర్కు చాలా ముఖ్యమైన దాని గురించి మాట్లాడుతాము: డేటా నిర్మాణాలు. వికీపీడియా ఇలా చెబుతోంది: " డేటా నిర్మాణం అనేది డేటా ఆర్గనైజేషన్, మేనేజ్మెంట్ మరియు స్టోరేజ్ ఫార్మాట్, ఇది సమర్థవంతమైన యాక్సెస్ మరియు సవరణను అనుమతిస్తుంది. మరింత ఖచ్చితంగా, డేటా స్ట్రక్చర్ అనేది డేటా విలువలు, వాటి మధ్య సంబంధాలు మరియు విధులు లేదా కార్యకలాపాల సమాహారం. డేటాకు వర్తింపజేయబడింది." నిర్వచనం కొంచెం గందరగోళంగా ఉంది, కానీ దాని సారాంశం స్పష్టంగా ఉంది. డేటా స్ట్రక్చర్ అనేది భవిష్యత్ ఉపయోగం కోసం మేము డేటాను నిల్వ చేసే ఒక రకమైన రిపోజిటరీ. ప్రోగ్రామింగ్లో, అనేక రకాల డేటా స్ట్రక్చర్లు ఉన్నాయి. నిర్దిష్ట సమస్యలను పరిష్కరించేటప్పుడు, చాలా తరచుగా చాలా ముఖ్యమైన విషయం సమస్య కోసం చాలా సరిఅయిన డేటా నిర్మాణాన్ని ఎంచుకోవడం. మరియు మీరు వారిలో చాలా మందితో ఇప్పటికే సుపరిచితులు! ఉదాహరణకు, మీకు శ్రేణుల గురించి తెలుసు. మరియు మీకు కూడా సుపరిచితమే
Map
(ఈ డేటా నిర్మాణాన్ని "నిఘంటువు" లేదా "అనుబంధ శ్రేణి"గా కూడా సూచించవచ్చు). డేటా నిర్మాణాలు ఏదైనా నిర్దిష్ట భాషతో ముడిపడి ఉండవని అర్థం చేసుకోవడం చాలా ముఖ్యం. అవి కేవలం నైరూప్య "బ్లూప్రింట్లు", ప్రతి ప్రోగ్రామింగ్ భాష దాని స్వంత తరగతులను లేదా నిర్దిష్ట నిర్మాణం యొక్క అమలులను రూపొందించడానికి ఉపయోగిస్తుంది. ఉదాహరణకు, అత్యంత ప్రసిద్ధ డేటా నిర్మాణాలలో ఒకటి లింక్డ్ లిస్ట్. మీరు వికీపీడియాకు వెళ్లి, ఇది ఎలా పని చేస్తుందో మరియు దాని ప్రయోజనాలు మరియు అప్రయోజనాలు గురించి చదవండి. బహుశా దాని నిర్వచనం మీకు సుపరిచితం అనిపించవచ్చు :) "లింక్ చేయబడిన జాబితా అనేది డేటా మూలకాల యొక్క సరళ సేకరణ, దీని క్రమం మెమరీలో వాటి భౌతిక స్థానం ద్వారా ఇవ్వబడదు. బదులుగా, ప్రతి మూలకం తదుపరి దానిని సూచిస్తుంది." అది మన ప్రియమైన వ్యక్తిని వివరిస్తుంది LinkedList
, కాదా? అవును, మరియు అది అంతే :) జావాలో, "లింక్డ్ లిస్ట్" డేటా స్ట్రక్చర్ క్లాస్ ద్వారా అమలు చేయబడుతుంది LinkedList
. కానీ ఇతర భాషలు కూడా లింక్డ్ జాబితాలను అమలు చేస్తాయి! పైథాన్లో, ఈ డేటా నిర్మాణాన్ని "" అంటారు llist
. LinkedList
జావాలో వలె స్కాలాలో దీనిని "" అంటారు . లింక్ చేయబడిన జాబితా అనేది ప్రాథమిక సాధారణ డేటా నిర్మాణాలలో ఒకటి, కాబట్టి ఇది ఏదైనా ఆధునిక ప్రోగ్రామింగ్ భాషలో అమలు చేయబడిందని మీరు కనుగొంటారు. అనుబంధ శ్రేణుల విషయంలో కూడా ఇదే నిజం. వికీపీడియా నుండి నిర్వచనం ఇక్కడ ఉంది: "అనుబంధ శ్రేణి, మ్యాప్, సింబల్ టేబుల్ లేదా డిక్షనరీ అనేది (కీ, విలువ) జతల సేకరణతో కూడిన ఒక నైరూప్య డేటా రకం, అటువంటి ప్రతి సాధ్యం కీ సేకరణలో ఒకేసారి కనిపిస్తుంది." అది మీకు ఏదైనా గుర్తు చేస్తుందా? :) అవును. మాకు జావా డెవలపర్ల కోసం, అనుబంధ శ్రేణిMap
ఇంటర్ఫేస్. కానీ ఈ డేటా స్ట్రక్చర్ ఇతర భాషల్లో కూడా అమలు చేయబడుతుంది! ఉదాహరణకు, C# ప్రోగ్రామర్లు దీనిని "డిక్షనరీ" పేరుతో తెలుసుకుంటారు. మరియు రూబీలో, ఇది "హాష్" అనే తరగతిలో అమలు చేయబడుతుంది. బాగా, మీరు పాయింట్ పొందుతారు: డేటా నిర్మాణాలు ప్రోగ్రామింగ్లో సార్వత్రిక భావనలు మరియు ప్రతి ప్రోగ్రామింగ్ భాష వాటిని దాని స్వంత మార్గంలో అమలు చేస్తుంది. ఈ రోజు మనం అటువంటి రెండు నిర్మాణాలను అధ్యయనం చేస్తాము - స్టాక్ మరియు క్యూ - మరియు అవి జావాలో ఎలా అమలు చేయబడతాయో చూద్దాం.
జావాలో స్టాక్లు
స్టాక్ అనేది బాగా తెలిసిన డేటా నిర్మాణం. ఇది చాలా సులభం. మన దైనందిన జీవితంలో కొన్ని అంశాలు స్టాక్గా "అమలు" చేయబడతాయి. ఈ సాధారణ పరిస్థితిని ఊహించండి: మీరు ఒక హోటల్లో బస చేస్తున్నారు మరియు రోజులో మీకు కొన్ని వ్యాపార లేఖలు వచ్చాయి. ఆ సమయంలో మీరు మీ గదిలో లేరు, కాబట్టి హోటల్ క్లర్క్ మీ డెస్క్పై ఇన్కమింగ్ లెటర్లను ఉంచారు. మొదట, అతను మొదటి అక్షరాన్ని డెస్క్ మీద ఉంచాడు. అప్పుడు రెండవ లేఖ వచ్చింది, మరియు అతను దానిని మొదటిదానిపై ఉంచాడు . అతను మూడవ అక్షరాన్ని రెండవదానిపైన, నాల్గవ అక్షరాన్ని మూడవదానిపై ఉంచాడు. ఇప్పుడు, ఒక సాధారణ ప్రశ్నకు సమాధానం ఇవ్వండి: మీరు మీ గదికి తిరిగి వచ్చి టేబుల్పై ఉన్న స్టాక్ని చూసినప్పుడు మీరు మొదట ఏ లేఖను చదువుతారు ? సరిగ్గా, మీరు పైభాగంలో చదువుతారులేఖ. అంటే, ఇటీవల వచ్చినది . స్టాక్ ఎలా పని చేస్తుంది. ఈ సూత్రాన్ని "లాస్ట్ ఇన్ ఫస్ట్ అవుట్" (LIFO) అంటారు . స్టాక్లు దేనికి మంచివి? సరే, మీరు జావాలో ఏదో ఒక రకమైన కార్డ్ గేమ్ని సృష్టిస్తున్నారని అనుకుందాం. కార్డుల డెక్ టేబుల్ మీద ఉంది. ఆడిన కార్డులు విస్మరించబడ్డాయి. డ్రా డెక్ మరియు డిస్కార్డ్ పైల్ రెండింటినీ అమలు చేయడానికి మీరు రెండు స్టాక్లను ఉపయోగించవచ్చు. ఆటగాళ్ళు తమ కార్డులను డెక్ పై నుండి తీసుకుంటారు, మీ వ్యాపార అక్షరాలతో అదే సూత్రాన్ని అనుసరిస్తారు. ఆటగాళ్ళు డిస్కార్డ్ పైల్లో కార్డ్లను ఉంచినప్పుడు, కొత్తగా విస్మరించబడిన కార్డులు పాత వాటి పైన ఉంచబడతాయి. స్టాక్ ఆధారంగా అమలు చేయబడిన గేమ్లో మా మొదటి ప్రయత్నం ఇక్కడ ఉంది:
public class Card {
public Card(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Card{" +
"name='" + name + '\'' +
'}';
}
}
import java.util.Stack;
public class SimpleCardGame {
// Draw deck
private Stack<Card> deck;
// Discard pile
private Stack<Card> discardPile;
public Card getCardFromDeck() {
return deck.pop();
}
public void discard(Card card) {
discardPile.push(card);
}
public Card lookAtTopCard() {
return deck.peek();
}
// ...getters, setters, etc.
}
మేము ఇంతకు ముందే చెప్పినట్లుగా, మనకు రెండు స్టాక్లు ఉన్నాయి: డ్రా డెక్ మరియు డిస్కార్డ్ పైల్. జావాలో, స్టాక్ డేటా నిర్మాణం తరగతిలో అమలు చేయబడుతుంది java.util.Stack
. మా కార్డ్ గేమ్లో ఆటగాళ్ల చర్యలను వివరించే 3 పద్ధతులు ఉన్నాయి:
- డెక్ నుండి కార్డు తీసుకోండి (
getCardFromDeck()
పద్ధతి) - కార్డును విస్మరించండి (
discard()
పద్ధతి) lookAtTopCard()
టాప్ కార్డ్ ( పద్ధతి) చూడండి . ఇది "ఇంటెలిజెన్స్" బోనస్ అని చెప్పండి, ఇది గేమ్లో తదుపరి ఏ కార్డ్ వస్తుందో తెలుసుకోవడానికి ఆటగాడిని అనుమతిస్తుంది.
push()
— స్టాక్ పైభాగానికి ఒక అంశాన్ని జోడిస్తుంది. మనం డిస్కార్డ్ పైల్కి కార్డ్ని పంపినప్పుడు, అది పైల్ పైకి వెళ్తుందిpop()
— స్టాక్ నుండి టాప్ ఎలిమెంట్ను తీసివేసి, దాన్ని తిరిగి అందిస్తుంది. ఆటగాడు కార్డును గీసే చర్యలను అమలు చేయడానికి ఈ పద్ధతి సరైనది.peek()
— స్టాక్ యొక్క టాప్ ఎలిమెంట్ను తిరిగి ఇస్తుంది, కానీ స్టాక్ నుండి దాన్ని తీసివేయదు
import java.util.Stack;
public class Main3 {
public static void main(String[] args) {
// Create a deck and add cards to it
Stack<Card> deck = new Stack<>();
deck.push(new Card("Ragnaros"));
deck.push(new Card("Patches the Pirate"));
deck.push(new Card("Sylvanas Windrunner"));
deck.push(new Card("Millhouse Manastorm"));
deck.push (new Card ("Edwin VanCleef"));
// Create the discard pile
Stack<Card> discardPile = new Stack<>();
// Start the game
SimpleCardGame game = new SimpleCardGame();
game.setDeck(deck);
game.setDiscardPile(discardPile);
// The first player draws 3 cards from the deck
Card card1 = game.getCardFromDeck();
Card card2 = game.getCardFromDeck();
Card card3 = game.getCardFromDeck();
System.out.println("Which cards went to the first player?");
System.out.println(card1);
System.out.println(card2);
System.out.println(card3);
// The first player discards 3 of his cards
game.discard(card1);
game.discard(card2);
game.discard(card3);
System.out.println("What cards are in the discard pile?");
System.out.println(game.getDiscardPile().pop());
System.out.println(game.getDiscardPile().pop());
System.out.println(game.getDiscardPile().pop());
}
}
మేము మా డెక్కి ఐదు కార్డులను జోడించాము. మొదటి ఆటగాడు వాటిలో 3 తీసుకున్నాడు. ఆమెకు ఏ కార్డులు వచ్చాయి? కన్సోల్ అవుట్పుట్:
Card{name='Edwin VanCleef"}
Card{name='Millhouse Manastorm'}
Card{name='Sylvanas Windrunner'}
కన్సోల్లో కార్డ్లు ప్రదర్శించబడే క్రమంలో శ్రద్ధ వహించండి. "ఎడ్విన్ వాన్క్లీఫ్" కార్డు చివరిగా డెక్లోకి వెళ్ళింది (ఇది ఐదవ కార్డ్), మరియు అది ఆటగాడు మొదట గీసిన కార్డు. "మిల్హౌస్" డెక్లోకి చివరిగా రెండవ స్థానంలో ఉంది మరియు ఆటగాడు దానిని రెండవ స్థానంలో నిలిచాడు. "సిల్వానాస్" పై నుండి మూడవ డెక్లోకి వెళ్ళాడు మరియు అది ఆటగాడు గీసిన మూడవ కార్డ్. తరువాత, ఆటగాడు కార్డులను విస్మరిస్తాడు. మొదట, ఆమె ఎడ్విన్ను, తర్వాత మిల్హౌస్ను, తర్వాత సిల్వానాస్ను విస్మరిస్తుంది. అప్పుడు మేము మా డిస్కార్డ్ పైల్లోని కార్డ్లను ఒక్కొక్కటిగా ప్రదర్శిస్తాము: కన్సోల్ అవుట్పుట్:
Card{name='Sylvanas Windrunner'}
Card{name='Millhouse Manastorm'}
Card{name='Edwin VanCleef"}
మరోసారి, స్టాక్ ఎలా పనిచేస్తుందో చూద్దాం! మా ఆటలో, డిస్కార్డ్ పైల్ కూడా ఒక స్టాక్ (డ్రా డెక్ లాగానే). "ఎడ్విన్ వాన్క్లీఫ్" మొదట విస్మరించబడింది. రెండవ కార్డు విస్మరించబడినది మిల్హౌస్ మనస్టోర్మ్, మరియు అది డిస్కార్డ్ పైల్లో ఎడ్విన్ పైన ఉంచబడింది. అప్పుడు సిల్వానాస్ విస్మరించబడింది మరియు ఈ కార్డు మిల్హౌస్ పైన ఉంచబడింది. మీరు గమనిస్తే, స్టాక్ గురించి సంక్లిష్టంగా ఏమీ లేదు. అయినప్పటికీ, మీరు ఈ డేటా నిర్మాణాన్ని తెలుసుకోవాలి - ఉద్యోగ ఇంటర్వ్యూల సమయంలో ఇది తరచుగా అడగబడుతుంది మరియు ఇది మరింత సంక్లిష్టమైన డేటా నిర్మాణాలను రూపొందించడానికి తరచుగా ఆధారం.
జావాలో క్యూ
క్యూ అనేది మరొక సాధారణ డేటా నిర్మాణం. స్టాక్లతో పాటు, జావాతో సహా అనేక ప్రోగ్రామింగ్ భాషలు కూడా క్యూ డేటా నిర్మాణాన్ని అమలు చేస్తాయి. క్యూ మరియు స్టాక్ మధ్య తేడా ఏమిటి? క్యూ అనేది LIFO సూత్రంపై కాకుండా FIFO సూత్రంపై ఆధారపడి ఉంటుంది ("ఫస్ట్ ఇన్, ఫస్ట్ అవుట్"). ఈ సూత్రం నిజ జీవితంలో ఒక సాధారణ లైన్ లేదా క్యూను పరిగణనలోకి తీసుకోవడం ద్వారా అర్థం చేసుకోవడం సులభం! ఉదాహరణకు, కిరాణా దుకాణం వద్ద ఒక లైన్. లైన్లో ఐదుగురు ఉంటే, ముందుగా లైన్లోకి ప్రవేశించిన వ్యక్తికి సేవ చేయవలసి ఉంటుంది . మరొక వ్యక్తి (ఇప్పటికే లైన్లో ఉన్న ఐదుగురితో పాటు) ఏదైనా కొనాలని కోరుకుంటే మరియు లైన్లో ఉంటే, అతను చివరిగా అందించబడ్డాడు, అంటే ఆరవది. క్యూతో పని చేస్తున్నప్పుడు, కొత్త అంశాలు తోకకు (వెనుకకు) జోడించబడతాయి మరియు మీరు ఒక మూలకాన్ని పొందాలనుకుంటే, అది తల (ముందు) నుండి తీసుకోబడుతుంది. క్యూ ఎలా పని చేస్తుందో మీరు గుర్తుంచుకోవలసిన ప్రధాన సూత్రం ఇది. మేము నిజ జీవితంలో తరచుగా క్యూలను కనుగొంటాము కాబట్టి క్యూ యొక్క ఆపరేషన్ చాలా స్పష్టమైనది. జావాలో క్యూ తరగతి ద్వారా కాకుండా ఇంటర్ఫేస్ ద్వారా సూచించబడుతుందని విడిగా గమనించాలి: క్యూ. ఇంకా ఏమిటంటే, జావాలో ఈ క్యూ ఇంటర్ఫేస్కు చాలా ఇంప్లిమెంటేషన్లు ఉన్నాయి. మేము ఒరాకిల్ డాక్యుమెంటేషన్ను పరిశీలిస్తే, 4 విభిన్న ఇంటర్ఫేస్లు, అలాగే అత్యంత ఆకర్షణీయమైన తరగతుల జాబితా, క్యూ ఇంటర్ఫేస్ను వారసత్వంగా పొందడాన్ని మనం చూస్తాము:
All known subinterfaces
BlockingDeque<E>, BlockingQueue<E>, Deque<E>, TransferQueue<E>
All known implementing classes
AbstractQueue, ArrayBlockingQueue, ArrayDeque
ConcurrentLinkedDeque, ConcurrentLinkedQueue, DelayQueue
LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue
PriorityBlockingQueue, PriorityQueue, SynchronousQueue
ఎంత పెద్ద జాబితా! అయితే, మీరు ప్రస్తుతం ఈ తరగతులు మరియు ఇంటర్ఫేస్లన్నింటినీ గుర్తుంచుకోవాల్సిన అవసరం లేదు — మీ తల పేలవచ్చు :) మేము చాలా ముఖ్యమైన మరియు ఆసక్తికరమైన అంశాలను మాత్రమే పరిశీలిస్తాము. ముందుగా, క్యూ యొక్క నాలుగు "సబింటర్ఫేస్లలో" ఒకదానికి శ్రద్ధ చూపుదాం: Deque . దాని ప్రత్యేకత ఏమిటి? A Deque
అనేది డబుల్-ఎండ్ క్యూ. ఇది సాధారణ క్యూ యొక్క కార్యాచరణను విస్తరిస్తుంది, రెండు చివరలకు (తల మరియు తోక వద్ద) మూలకాలను జోడించడానికి మరియు క్యూ యొక్క రెండు చివరల నుండి మూలకాలను తీసుకోవడానికి మిమ్మల్ని అనుమతిస్తుంది. సాఫ్ట్వేర్ అభివృద్ధిలో డబుల్-ఎండ్ క్యూలు విస్తృతంగా ఉపయోగించబడుతున్నాయి. మేము పైన అందించిన క్యూ తరగతుల జాబితాపై శ్రద్ధ వహించండి. జాబితా చాలా పొడవుగా ఉంది, కానీ ఇందులో తెలిసిన ఏదైనా ఉందా?
LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue
హా! ఇదిగో మా పాత స్నేహితుడు LinkedList
! కాబట్టి, ఇది క్యూ ఇంటర్ఫేస్ను అమలు చేస్తుందా? అయితే అది క్యూ ఎలా అవుతుంది? అన్నింటికంటే, a LinkedList
అనేది లింక్ చేయబడిన జాబితా! నిజమే, కానీ అది క్యూలో ఉండకుండా ఆపదు :) ఇది అమలు చేసే అన్ని ఇంటర్ఫేస్ల జాబితా ఇక్కడ ఉంది:
All implemented interfaces:
Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E>
మీరు చూడగలిగినట్లుగా, ఇంటర్ఫేస్ను LinkedList
అమలు చేస్తుంది Deque
(మళ్ళీ, దీని అర్థం డబుల్-ఎండ్ క్యూ). ఇది ఎందుకు అవసరం? ఇది a యొక్క ప్రారంభం మరియు ముగింపు నుండి మూలకాలను పొందేందుకు అనుమతిస్తుంది LinkedList
. ఇది ప్రారంభ మరియు ముగింపుకు అంశాలను జోడించడానికి కూడా అనుమతిస్తుంది. LinkedList
ఇంటర్ఫేస్ నుండి పొందే పద్ధతులు ఇక్కడ ఉన్నాయి Deque
:
peekFirst()
— మొదటి మూలకాన్ని తిరిగి ఇస్తుంది (కానీ దానిని క్యూ నుండి తీసివేయదు).peekLast()
— చివరి మూలకాన్ని తిరిగి ఇస్తుంది (కానీ దానిని క్యూ నుండి తీసివేయదు).pollFirst()
— క్యూ నుండి మొదటి మూలకాన్ని తిరిగి ఇస్తుంది మరియు దానిని తీసివేస్తుంది.pollLast()
- క్యూ నుండి చివరి అంశాన్ని తిరిగి ఇస్తుంది మరియు దానిని తీసివేస్తుంది.addFirst()
- క్యూ ముందు భాగంలో కొత్త అంశాన్ని జోడిస్తుంది.addLast()
- క్యూ చివర ఒక అంశాన్ని జోడిస్తుంది.
LinkedList
డబుల్-ఎండ్ క్యూ యొక్క కార్యాచరణను పూర్తిగా అమలు చేస్తుంది! మరియు మీ ప్రోగ్రామ్లో మీకు అలాంటి కార్యాచరణ అవసరం, దాన్ని ఎక్కడ కనుగొనాలో మీకు తెలుస్తుంది :) నేటి పాఠం ముగింపుకు వస్తోంది. ముగింపులో, అదనపు పఠనం కోసం నేను మీకు రెండు లింక్లను ఇస్తాను. ముందుగా, PriorityQueue గురించిన ఈ కథనానికి శ్రద్ధ వహించండి . ఇది అత్యంత ఆసక్తికరమైన మరియు ఉపయోగకరమైన అమలులలో ఒకటి Queue
. ఉదాహరణకు, మీ స్టోర్ వద్ద 50 మంది వ్యక్తులు లైన్లో వేచి ఉన్నారని, వారిలో 7 మంది VIP కస్టమర్లు ఉన్నారని అనుకుందాం. ప్రాధాన్యత క్యూ మీకు ముందుగా వాటిని అందించడానికి అనుమతిస్తుంది! చాలా ఉపయోగకరమైన విషయం, సరియైనదా? :) రెండవది, రాబర్ట్ లాఫోర్ పుస్తకం "జావాలోని డేటా స్ట్రక్చర్స్ అండ్ అల్గారిథమ్స్" గురించి మరోసారి ప్రస్తావించడం బాధ కలిగించదు.. ఈ పుస్తకాన్ని చదవడం ద్వారా, మీరు చాలా డేటా స్ట్రక్చర్లను (స్టాక్ మరియు క్యూతో సహా) నేర్చుకోవడమే కాకుండా, వాటిలో చాలా వాటిని మీరే అమలు చేస్తారు! ఉదాహరణకు, జావాకు స్టాక్ క్లాస్ లేకపోతే ఏమి చేయాలి? మీ ప్రోగ్రామ్ కోసం మీకు అలాంటి డేటా నిర్మాణం అవసరమైతే మీరు ఏమి చేస్తారు? మీరు దానిని మీరే వ్రాయవలసి ఉంటుంది. మీరు లాఫోర్ పుస్తకాన్ని చదివేటప్పుడు , మీరు తరచుగా అలానే చేస్తారు. ఫలితంగా, డేటా స్ట్రక్చర్లపై మీ అవగాహన మీరు సిద్ధాంతం యొక్క సాధారణ అధ్యయనం నుండి పొందగలిగే దానికంటే చాలా లోతుగా ఉంటుంది :) మేము ఈ రోజు కోసం సిద్ధాంతాన్ని మూసివేస్తున్నాము, కానీ అభ్యాసం లేని సిద్ధాంతం ఏమీ లేదు! పనులు స్వయంగా పరిష్కరించబడవు, కాబట్టి వాటిని పరిష్కరించడానికి ఇది సమయం! :)
GO TO FULL VERSION