Implement Set using Array.

本文深入探讨了ArraySet的实现细节,包括如何通过自动扩容解决容量不足的问题,以及在删除元素时采用的技巧来保持数据结构的高效性。此外,还讨论了在Pivotal面试中可能遇到的相关陷阱。

参考链接:http://faculty.washington.edu/moishe/javademos/ch03%20Code/jss2/ArraySet.java

被Pivotal的面试官给问到了,trick的地方在于remove的那一块,要把最后的元素跟自己remove的元素进行互换,然后count--;还有,自动扩容那块,构造函数需要两个,一个默认的,一个是可以限定side的。然后扩容的时候,阔完了,需要把larger 给contents。这都是容易错的地方,我当时就忘记赋值了。两个地方没有做好,然后就挂掉了。

//********************************************************************
//  ArraySet.java       Author: Lewis/Chase
//
//  Represents an array implementation of a set.
//********************************************************************

package jss2;
import jss2.exceptions.*;
import java.util.*;

public class ArraySet<T> implements SetADT<T>
{
   private static Random rand = new Random();

   private final int DEFAULT_CAPACITY = 100;
   private final int NOT_FOUND = -1;

   private int count;  // the current number of elements in the set 

   private T[] contents; 

   //-----------------------------------------------------------------
   //  Creates an empty set using the default capacity.
   //-----------------------------------------------------------------
   public ArraySet()
   {
      count = 0;
      contents = (T[])(new Object[DEFAULT_CAPACITY]);
   }

   //-----------------------------------------------------------------
   //  Creates an empty set using the specified capacity.
   //-----------------------------------------------------------------
   public ArraySet (int initialCapacity)
   {
      count = 0;
      contents = (T[])(new Object[initialCapacity]);
   }

   //-----------------------------------------------------------------
   //  Adds the specified element to the set if it's not already
   //  present. Expands the capacity of the set array if necessary.
   //-----------------------------------------------------------------
   public void add (T element)
   {
      if (!(contains(element)))
      {
         if (size() == contents.length) 
            expandCapacity();

         contents[count] = element;
         count++;
      }
   }

   //-----------------------------------------------------------------
   //  Adds the contents of the parameter to this set.
   //-----------------------------------------------------------------
   public void addAll (SetADT<T> set)
   {
      Iterator<T> scan = set.iterator();

      while (scan.hasNext())
         add (scan.next());
   }


   //-----------------------------------------------------------------
   //  Removes a random element from the set and returns it. Throws
   //  an EmptySetException if the set is empty.
   //-----------------------------------------------------------------
   public T removeRandom() throws EmptySetException
   {
      if (isEmpty())
         throw new EmptySetException();

      int choice = rand.nextInt(count);

      T result = contents[choice];

      contents[choice] = contents[count-1];  // fill the gap
      contents[count-1] = null;
      count--;
 
      return result;
   }

   //-----------------------------------------------------------------
   //  Removes the specified element from the set and returns it.
   //  Throws an EmptySetException if the set is empty and a
   //  NoSuchElementException if the target is not in the set.
   //-----------------------------------------------------------------
   public T remove (T target) throws EmptySetException,
                                     NoSuchElementException
   {
      int search = NOT_FOUND;

      if (isEmpty())
         throw new EmptySetException();

      for (int index=0; index < count && search == NOT_FOUND; index++)
         if (contents[index].equals(target))
            search = index;

      if (search == NOT_FOUND)
         throw new NoSuchElementException();

      T result = contents[search];

      contents[search] = contents[count-1];
      contents[count-1] = null;
      count--;
 
      return result;
   }
   
   //-----------------------------------------------------------------
   //  Returns a new set that is the union of this set and the
   //  parameter.
   //-----------------------------------------------------------------
   public SetADT<T> union (SetADT<T> set)
   {
      ArraySet<T> both = new ArraySet<T>();

      for (int index = 0; index < count; index++)
         both.add (contents[index]);

      Iterator<T> scan = set.iterator();
      while (scan.hasNext())
         both.add (scan.next());

      return both;
   }

   //-----------------------------------------------------------------
   //  Returns true if this set contains the specified target
   //  element.
   //-----------------------------------------------------------------
   public boolean contains (T target)
   {
      int search = NOT_FOUND;

      for (int index=0; index < count && search == NOT_FOUND; index++)
         if (contents[index].equals(target))
            search = index;

      return (search != NOT_FOUND);
   }

   //-----------------------------------------------------------------
   //  Returns true if this set contains exactly the same elements
   //  as the parameter.
   //-----------------------------------------------------------------
   public boolean equals (SetADT<T> set)
   {
      boolean result = false;
      ArraySet<T> temp1 = new ArraySet<T>();
      ArraySet<T> temp2 = new ArraySet<T>();
      T obj;

      if (size() == set.size())
      { 
         temp1.addAll(this);
         temp2.addAll(set);

         Iterator<T> scan = set.iterator();

         while (scan.hasNext())
         {
            obj = scan.next();   
            if (temp1.contains(obj))
            {
               temp1.remove(obj);
               temp2.remove(obj);
            }
		  
         }

        result = (temp1.isEmpty() && temp2.isEmpty());
      }

      return result;
   }

   //-----------------------------------------------------------------
   //  Returns true if this set is empty and false otherwise. 
   //-----------------------------------------------------------------
   public boolean isEmpty()
   {
      return (count == 0);
   }
 
   //-----------------------------------------------------------------
   //  Returns the number of elements currently in this set.
   //-----------------------------------------------------------------
   public int size()
   {
      return count;
   }

   //-----------------------------------------------------------------
   //  Returns an iterator for the elements currently in this set.
   //-----------------------------------------------------------------
   public Iterator<T> iterator()
   {
      return new ArrayIterator<T> (contents, count);
   }

   //-----------------------------------------------------------------
   //  Returns a string representation of this set. 
   //-----------------------------------------------------------------
   public String toString()
   {
      String result = "";

      for (int index=0; index < count; index++) 
         result = result + contents[index].toString() + "\n";

      return result;
   }

   //-----------------------------------------------------------------
   //  Creates a new array to store the contents of the set with
   //  twice the capacity of the old one.
   //-----------------------------------------------------------------
   private void expandCapacity()
   {
      T[] larger = (T[])(new Object[contents.length*2]);

      for (int index=0; index < contents.length; index++)
         larger[index] = contents[index];

      contents = larger;
   }
}


classdef WebSocketClient < handle %WEBSOCKETCLIENT WebSocketClient is an ABSTRACT class that allows %MATLAB to start a java-websocket client instance and connect to a %WebSocket server. % % In order to make a valid implementation of the class, some methods % must be defined in the superclass: % onOpen(obj,message) % onTextMessage(obj,message) % onBinaryMessage(obj,bytearray) % onError(obj,message) % onClose((obj,message) % The "callback" behavior of the client can be defined there. If % the client needs to perform actions that are not responses to a % server-caused event, these actions must be performed outside of the % callback methods. properties (SetAccess = private) URI % The URI of the server Secure = false % True if the connection is using WebSocketSecure Status = false % Status of the connection, true if the connection is open ClientObj % Java-WebSocket client object end properties (Access = private) HttpHeaders = {} % Cell array of additional headers {'key1', 'value1',...} UseKeyStore = false KeyStore % Location of the keystore StorePassword % Keystore password KeyPassword % Key password end methods function obj = WebSocketClient(URI,varargin) % WebSocketClient Constructor % Creates a java client to connect to the designated server. % Arguments: URI, [keyStore, storePassword, keyPassword], [httpHeaders] % The URI must be of the form 'ws[s]://some.server.org:30000'. obj.URI = lower(URI); if strfind(obj.URI,'wss') obj.Secure = true; end % Parse optional arguments if nargin == 2 obj.HttpHeaders = varargin{1}; elseif obj.Secure && (nargin == 4 || nargin == 5) obj.UseKeyStore = true; obj.KeyStore = varargin{1}; obj.StorePassword = varargin{2}; obj.KeyPassword = varargin{3}; if nargin == 5 obj.HttpHeaders = varargin{4}; end elseif obj.Secure && nargin > 2 error('Invalid number of arguments for secure connection with keystore!'); elseif ~obj.Secure && nargin > 2 warning(['You are passing a keystore, but the given '... 'server URI does not start with "wss". '... 'The connection will not be secure.']); end % Check headers are valid if ~iscellstr(obj.HttpHeaders) || logical(mod(length(obj.HttpHeaders),2)) error(['Invalid HTTP header format! You must pass a cell array'... 'of key/value pairs: {''key1'', ''value1'',...}']); end % Connect the client to the server obj.open(); end function status = get.Status(obj) % Get the status of the connection if isempty(obj.ClientObj) status = false; else status = obj.ClientObj.isOpen(); end end function open(obj) % Open the connection to the server % Create the java client object in with specified URI if obj.Status; warning('Connection is already open!');return; end import io.github.jebej.matlabwebsocket.* uri = handle(java.net.URI(obj.URI)); headers = handle(java.util.HashMap()); for i = 1:2:length(obj.HttpHeaders)-1 headers.put(obj.HttpHeaders{i}, obj.HttpHeaders{i+1}); end if obj.Secure && ~obj.UseKeyStore obj.ClientObj = handle(MatlabWebSocketSSLClient(uri, headers),'CallbackProperties'); elseif obj.Secure && obj.UseKeyStore obj.ClientObj = handle(MatlabWebSocketSSLClient(uri, headers,... obj.KeyStore,obj.StorePassword,obj.KeyPassword),'CallbackProperties'); else obj.ClientObj = handle(MatlabWebSocketClient(uri, headers),'CallbackProperties'); end % Set callbacks set(obj.ClientObj,'OpenCallback',@obj.openCallback); set(obj.ClientObj,'TextMessageCallback',@obj.textMessageCallback); set(obj.ClientObj,'BinaryMessageCallback',@obj.binaryMessageCallback); set(obj.ClientObj,'ErrorCallback',@obj.errorCallback); set(obj.ClientObj,'CloseCallback',@obj.closeCallback); % Connect to the websocket server obj.ClientObj.connectBlocking(); end function close(obj) % Close the websocket connection and explicitely delete the % java client object if ~obj.Status; warning('Connection is already closed!');return; end obj.ClientObj.closeBlocking() delete(obj.ClientObj); obj.ClientObj = []; end function delete(obj) % Destructor % Closes the websocket if it's open. if obj.Status obj.close(); end end function send(obj,message) % Send a message to the server if ~obj.Status; warning('Connection is closed!');return; end if ~ischar(message) && ~isa(message,'int8') && ~isa(message,'uint8') error('You can only send character arrays or byte arrays!'); end obj.ClientObj.send(message); end end % Implement these methods in a subclass. methods (Abstract, Access = protected) onOpen(obj,message) onTextMessage(obj,message) onBinaryMessage(obj,bytearray) onError(obj,message) onClose(obj,message) end % Private methods triggered by the callbacks defined above. methods (Access = private) function openCallback(obj,~,e) % Define behavior in an onOpen method of a subclass obj.onOpen(char(e.message)); end function textMessageCallback(obj,~,e) % Define behavior in an onTextMessage method of a subclass obj.onTextMessage(char(e.message)); end function binaryMessageCallback(obj,~,e) % Define behavior in an onBinaryMessage method of a subclass obj.onBinaryMessage(e.blob.array); end function errorCallback(obj,~,e) % Define behavior in an onError method of a subclass obj.onError(char(e.message)); end function closeCallback(obj,~,e) % Define behavior in an onClose method of a subclass obj.onClose(char(e.message)); % Delete java client object if needed if ~isvalid(obj); return; end delete(obj.ClientObj); obj.ClientObj = []; end end end
08-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值